From 87a9ba5f2f5b9c3cde675c238ce718147417df03 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 15 Mar 2015 16:52:55 -0400 Subject: SHERLOCK: Initial commit --- engines/sherlock/configure.engine | 3 + engines/sherlock/decompress.cpp | 82 +++++++++++++ engines/sherlock/decompress.h | 36 ++++++ engines/sherlock/detection.cpp | 125 ++++++++++++++++++++ engines/sherlock/detection_tables.h | 47 ++++++++ engines/sherlock/graphics.cpp | 45 +++++++ engines/sherlock/graphics.h | 43 +++++++ engines/sherlock/inventory.h | 40 +++++++ engines/sherlock/journal.cpp | 40 +++++++ engines/sherlock/journal.h | 46 ++++++++ engines/sherlock/module.mk | 22 ++++ engines/sherlock/resources.cpp | 219 +++++++++++++++++++++++++++++++++++ engines/sherlock/resources.h | 86 ++++++++++++++ engines/sherlock/room.cpp | 32 +++++ engines/sherlock/room.h | 102 ++++++++++++++++ engines/sherlock/scalpel/scalpel.cpp | 40 +++++++ engines/sherlock/scalpel/scalpel.h | 45 +++++++ engines/sherlock/sherlock.cpp | 81 +++++++++++++ engines/sherlock/sherlock.h | 91 +++++++++++++++ engines/sherlock/sound.h | 39 +++++++ engines/sherlock/sprite.cpp | 142 +++++++++++++++++++++++ engines/sherlock/sprite.h | 56 +++++++++ engines/sherlock/talk.cpp | 30 +++++ engines/sherlock/talk.h | 49 ++++++++ engines/sherlock/tattoo/tattoo.cpp | 38 ++++++ engines/sherlock/tattoo/tattoo.h | 45 +++++++ engines/sherlock/vdaplayer.h | 34 ++++++ 27 files changed, 1658 insertions(+) create mode 100644 engines/sherlock/configure.engine create mode 100644 engines/sherlock/decompress.cpp create mode 100644 engines/sherlock/decompress.h create mode 100644 engines/sherlock/detection.cpp create mode 100644 engines/sherlock/detection_tables.h create mode 100644 engines/sherlock/graphics.cpp create mode 100644 engines/sherlock/graphics.h create mode 100644 engines/sherlock/inventory.h create mode 100644 engines/sherlock/journal.cpp create mode 100644 engines/sherlock/journal.h create mode 100644 engines/sherlock/module.mk create mode 100644 engines/sherlock/resources.cpp create mode 100644 engines/sherlock/resources.h create mode 100644 engines/sherlock/room.cpp create mode 100644 engines/sherlock/room.h create mode 100644 engines/sherlock/scalpel/scalpel.cpp create mode 100644 engines/sherlock/scalpel/scalpel.h create mode 100644 engines/sherlock/sherlock.cpp create mode 100644 engines/sherlock/sherlock.h create mode 100644 engines/sherlock/sound.h create mode 100644 engines/sherlock/sprite.cpp create mode 100644 engines/sherlock/sprite.h create mode 100644 engines/sherlock/talk.cpp create mode 100644 engines/sherlock/talk.h create mode 100644 engines/sherlock/tattoo/tattoo.cpp create mode 100644 engines/sherlock/tattoo/tattoo.h create mode 100644 engines/sherlock/vdaplayer.h diff --git a/engines/sherlock/configure.engine b/engines/sherlock/configure.engine new file mode 100644 index 0000000000..a56129a8f0 --- /dev/null +++ b/engines/sherlock/configure.engine @@ -0,0 +1,3 @@ +# This file is included from the main "configure" script +# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] +add_engine sherlock "The Lost Files of Sherlock Holmes" no diff --git a/engines/sherlock/decompress.cpp b/engines/sherlock/decompress.cpp new file mode 100644 index 0000000000..61110be840 --- /dev/null +++ b/engines/sherlock/decompress.cpp @@ -0,0 +1,82 @@ +/* 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 "sherlock/decompress.h" + +namespace Sherlock { + +/** + * Decompresses an LZW compressed resource. If no outSize is specified, it will + * decompress the entire resource. If, however, an explicit size is specified, + * it will decompress only up to that many bytes from the stream starting at + * whatever position it was previously. + */ +Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source, int32 outSize) { + if (outSize == -1) { + source.seek(5); + outSize = source.readSint32LE(); + } + + byte lzWindow[4096]; + uint16 lzWindowPos; + uint16 cmd; + + byte *outBuffer = new byte[outSize]; + byte *outBufferEnd = outBuffer + outSize; + Common::MemoryReadStream *outS = new Common::MemoryReadStream(outBuffer, outSize, DisposeAfterUse::YES); + + memset(lzWindow, 0xFF, 0xFEE); + lzWindowPos = 0xFEE; + cmd = 0; + + while (1) { + cmd >>= 1; + if (!(cmd & 0x100)) { + cmd = source.readByte() | 0xFF00; + } + if (cmd & 1) { + byte literal = source.readByte(); + *outBuffer++ = literal; + lzWindow[lzWindowPos] = literal; + lzWindowPos = (lzWindowPos + 1) & 0x0FFF; + } else { + int copyPos, copyLen; + copyPos = source.readByte(); + copyLen = source.readByte(); + copyPos = copyPos | ((copyLen & 0xF0) << 4); + copyLen = (copyLen & 0x0F) + 3; + while (copyLen--) { + byte literal = lzWindow[copyPos]; + copyPos = (copyPos + 1) & 0x0FFF; + *outBuffer++ = literal; + lzWindow[lzWindowPos] = literal; + lzWindowPos = (lzWindowPos + 1) & 0x0FFF; + } + } + if (outBuffer >= outBufferEnd) + break; + } + + return outS; +} + +} // namespace Sherlock diff --git a/engines/sherlock/decompress.h b/engines/sherlock/decompress.h new file mode 100644 index 0000000000..330e018115 --- /dev/null +++ b/engines/sherlock/decompress.h @@ -0,0 +1,36 @@ +/* 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 SHERLOCK_DECOMPRESS_H +#define SHERLOCK_DECOMPRESS_H + +#include "common/memstream.h" + +namespace Sherlock { + +#include "common/stream.h" + +Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source, int32 outSize = -1); + +} // namespace Sherlock + +#endif diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp new file mode 100644 index 0000000000..f207bb69d9 --- /dev/null +++ b/engines/sherlock/detection.cpp @@ -0,0 +1,125 @@ +/* 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 "sherlock/sherlock.h" +#include "sherlock/scalpel/scalpel.h" +#include "sherlock/tattoo/tattoo.h" +#include "engines/advancedDetector.h" + +namespace Sherlock { + +#define MAX_SAVES 99 + +struct SherlockGameDescription { + ADGameDescription desc; + + int gameID; + uint32 features; +}; + +uint32 SherlockEngine::getGameID() const { + return _gameDescription->gameID; +} + +uint32 SherlockEngine::getGameFeatures() const { + return _gameDescription->features; +} + +Common::Platform SherlockEngine::getPlatform() const { + return _gameDescription->desc.platform; +} + +} // End of namespace Sherlock + +static const PlainGameDescriptor sherlockGames[] = { + {"sherlock", "The Lost Files of Sherlock Holmes"}, + { "scalpel", "The Case of the Serrated Scalpel" }, + { "rosetattoo", "The Case of the Rose Tattoo" }, + {0, 0} +}; + +#include "sherlock/detection_tables.h" + +class SherlockMetaEngine : public AdvancedMetaEngine { +public: + SherlockMetaEngine() : AdvancedMetaEngine(Sherlock::gameDescriptions, sizeof(Sherlock::gameDescriptions), sherlockGames) {} + + virtual const char *getName() const { + return "Sherlock Engine"; + } + + virtual const char *getOriginalCopyright() const { + return "Sherlock Engine (C) 1992-1996 Mythos Software, 1992-1996 (C) Electronic Arts"; + } + + virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; + virtual bool hasFeature(MetaEngineFeature f) const; + virtual SaveStateList listSaves(const char *target) const; + virtual int getMaximumSaveSlot() const; + virtual void removeSaveState(const char *target, int slot) const; + SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const; +}; + +bool SherlockMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { + const Sherlock::SherlockGameDescription *gd = (const Sherlock::SherlockGameDescription *)desc; + if (gd) { + switch (gd->gameID) { + case Sherlock::GType_SerratedScalpel: + *engine = new Sherlock::Scalpel::ScalpelEngine(syst, gd); + break; + case Sherlock::GType_RoseTattoo: + *engine = new Sherlock::Tattoo::TattooEngine(syst, gd); + break; + default: + error("Unknown game"); + break; + } + } + return gd != 0; +} + +bool SherlockMetaEngine::hasFeature(MetaEngineFeature f) const { + return false; +} + +SaveStateList SherlockMetaEngine::listSaves(const char *target) const { + SaveStateList saveList; + return saveList; +} + +int SherlockMetaEngine::getMaximumSaveSlot() const { + return MAX_SAVES; +} + +void SherlockMetaEngine::removeSaveState(const char *target, int slot) const { +} + +SaveStateDescriptor SherlockMetaEngine::querySaveMetaInfos(const char *target, int slot) const { + return SaveStateDescriptor(); +} + + +#if PLUGIN_ENABLED_DYNAMIC(SHERLOCK) +REGISTER_PLUGIN_DYNAMIC(SHERLOCK, PLUGIN_TYPE_ENGINE, SherlockMetaEngine); +#else +REGISTER_PLUGIN_STATIC(SHERLOCK, PLUGIN_TYPE_ENGINE, SherlockMetaEngine); +#endif diff --git a/engines/sherlock/detection_tables.h b/engines/sherlock/detection_tables.h new file mode 100644 index 0000000000..1d7326058e --- /dev/null +++ b/engines/sherlock/detection_tables.h @@ -0,0 +1,47 @@ +/* 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. + * + */ + +namespace Sherlock { + +static const SherlockGameDescription gameDescriptions[] = { + { + // Case of the Serrated Scalpel - English + { + "scalpel", + 0, + { + { "talk.lib", 0, "ad0c4d6865edf15da4e9204c08815875", 238928 }, + AD_LISTEND + }, + Common::EN_ANY, + Common::kPlatformDOS, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOSPEECH) + }, + GType_SerratedScalpel, + 0 + }, + + { AD_TABLE_END_MARKER, 0, 0 } +}; + +} // End of namespace MADS diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp new file mode 100644 index 0000000000..f4a5bf1864 --- /dev/null +++ b/engines/sherlock/graphics.cpp @@ -0,0 +1,45 @@ +/* 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 "sherlock/graphics.h" + +namespace Sherlock { + +Surface::Surface(uint16 width, uint16 height) { + create(width, height, Graphics::PixelFormat::createFormatCLUT8()); +} + +Surface::~Surface() { + free(); +} + +void Surface::fillRect(int x1, int y1, int x2, int y2, byte color) { + Graphics::Surface::fillRect(Common::Rect(x1, y1, x2, y2), color); +} + +void Surface::drawSprite(int x, int y, SpriteFrame *spriteFrame, bool flipped, bool altFlag) { + + +} + + +} // End of namespace Sherlock diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h new file mode 100644 index 0000000000..64518a78c6 --- /dev/null +++ b/engines/sherlock/graphics.h @@ -0,0 +1,43 @@ +/* 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 SHERLOCK_GRAPHICS_H +#define SHERLOCK_GRAPHICS_H + +#include "common/rect.h" +#include "graphics/surface.h" + +#include "sherlock/sprite.h" + +namespace Sherlock { + +class Surface : public Graphics::Surface { +public: + Surface(uint16 width, uint16 height); + ~Surface(); + void fillRect(int x1, int y1, int x2, int y2, byte color); + void drawSprite(int x, int y, SpriteFrame *spriteFrame, bool flipped = false, bool altFlag = false); +}; + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h new file mode 100644 index 0000000000..de4a2d7758 --- /dev/null +++ b/engines/sherlock/inventory.h @@ -0,0 +1,40 @@ +/* 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 SHERLOCK_INVENTORY_H +#define SHERLOCK_INVENTORY_H + +#include "common/scummsys.h" + +namespace Sherlock { + +struct InventoryItem { + int stringIndex; + char name[12]; + char description[41]; + char name2[9]; + uint16 value; +}; + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp new file mode 100644 index 0000000000..ad7df48943 --- /dev/null +++ b/engines/sherlock/journal.cpp @@ -0,0 +1,40 @@ +/* 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 "sherlock/journal.h" + +namespace Sherlock { + +Journal::Journal() { + // Allow up to 1000 statements + _data.resize(1000); + + // Initialize fields + _count = 0; + _maxPage = 0; + _index = 0; + _sub = 0; + _up = _down = 0; + _page = 0; +} + +} // End of namespace Sherlock diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h new file mode 100644 index 0000000000..64158ff123 --- /dev/null +++ b/engines/sherlock/journal.h @@ -0,0 +1,46 @@ +/* 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 SHERLOCK_JOURNAL_H +#define SHERLOCK_JOURNAL_H + +#include "common/scummsys.h" +#include "common/array.h" + +namespace Sherlock { + +class Journal { +public: + Common::Array _data; + int _count; + int _maxPage; + int _index; + int _sub; + int _up, _down; + int _page; +public: + Journal(); +}; + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk new file mode 100644 index 0000000000..1dfcb3a5af --- /dev/null +++ b/engines/sherlock/module.mk @@ -0,0 +1,22 @@ +MODULE := engines/sherlock + +MODULE_OBJS = \ + scalpel/scalpel.o \ + tattoo/tattoo.o \ + decompress.o \ + detection.o \ + graphics.o \ + journal.o \ + resources.o \ + room.o \ + sherlock.o \ + sprite.o \ + talk.o + +# This module can be built as a plugin +ifdef BUILD_PLUGINS +PLUGIN := 1 +endif + +# Include common rules +include $(srcdir)/rules.mk diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp new file mode 100644 index 0000000000..e59e65abff --- /dev/null +++ b/engines/sherlock/resources.cpp @@ -0,0 +1,219 @@ +/* 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 "sherlock/resources.h" +#include "sherlock/decompress.h" +#include "common/debug.h" + +namespace Sherlock { + +Cache::Cache() { +} + +/** + * Returns true if a given file is currently being cached + */ +bool Cache::isCached(const Common::String &filename) const { + return _resources.contains(filename); +} + +/** + * Loads a file into the cache if it's not already present, and returns it. + * If the file is LZW compressed, automatically decompresses it and loads + * the uncompressed version into memory + */ +void Cache::load(const Common::String &filename) { + // First check if the entry already exists + if (_resources.contains(filename)) + return; + + // Allocate a new cache entry + _resources[filename] = CacheEntry(); + CacheEntry &cacheEntry = _resources[filename]; + + // Open the file for reading + Common::File f; + if (!f.open(filename)) + error("Could not read file - %s", filename.c_str()); + + // Check whether the file is compressed + const char LZW_HEADER[5] = { "LZV\x1a" }; + char header[5]; + f.read(header, 5); + bool isCompressed = !strncmp(header, LZW_HEADER, 5); + f.seek(0); + + if (isCompressed) { + // It's compressed, so decompress the file and store it's data in the cache entry + Common::SeekableReadStream *decompressed = decompressLZ(f); + cacheEntry.resize(decompressed->size()); + decompressed->read(&cacheEntry[0], decompressed->size()); + + delete decompressed; + } else { + // It's not, so read the raw data of the file into the cache entry + cacheEntry.resize(f.size()); + f.read(&cacheEntry[0], f.size()); + } + + f.close(); +} + +Common::SeekableReadStream *Cache::get(const Common::String &filename) const { + // Return a memory stream that encapsulates the data + const CacheEntry &cacheEntry = _resources[filename]; + return new Common::MemoryReadStream(&cacheEntry[0], cacheEntry.size()); +} + +/*----------------------------------------------------------------*/ + +Resources::Resources() { + _resourceIndex = -1; + + addToCache("vgs.lib"); + addToCache("talk.lib"); + addToCache("sequence.txt"); + addToCache("journal.txt"); + addToCache("portrait.lib"); +} + + +/** + * Adds the specified file to the cache. If it's a library file, takes care of + * loading it's index for future use + */ +void Resources::addToCache(const Common::String &filename) { + _cache.load(filename); + + // Check to see if the file is a library + Common::SeekableReadStream *stream = load(filename); + uint32 header = stream->readUint32BE(); + if (header == MKTAG('L', 'I', 'B', 26)) + loadLibraryIndex(filename, stream); + + delete stream; +} + +Common::SeekableReadStream *Resources::load(const Common::String &filename) { + // First check if the file is directly in the cache + if (_cache.isCached(filename)) + return _cache.get(filename); + + // Secondly, iterate through any loaded library file looking for a resource + // that has the same name + LibraryIndexes::iterator i; + for (i = _indexes.begin(); i != _indexes.end(); ++i) { + if ((*i)._value.contains(filename)) { + // Get a stream reference to the given library file + Common::SeekableReadStream *stream = load((*i)._key); + LibraryEntry &entry = (*i)._value[filename]; + _resourceIndex = entry._index; + + stream->seek(entry._offset); + Common::SeekableReadStream *resStream = stream->readStream(entry._size); + + delete stream; + return resStream; + } + } + + // At this point, fall back on a physical file with the given name + Common::File f; + if (!f.open(filename)) + error("Could not load file - %s", filename.c_str()); + + Common::SeekableReadStream *stream = f.readStream(f.size()); + f.close(); + + return stream; +} + +/** + * Loads a specific resource from a given library file + */ +Common::SeekableReadStream *Resources::load(const Common::String &filename, const Common::String &libraryFile) { + // Open up the library for access + Common::SeekableReadStream *libStream = load(libraryFile); + + // Check if the library has already had it's index read, and if not, load it + if (!_indexes.contains(libraryFile)) + loadLibraryIndex(libraryFile, libStream); + + // Extract the data for the specified resource and return it + LibraryEntry &entry = _indexes[libraryFile][filename]; + libStream->seek(entry._offset); + Common::SeekableReadStream *stream = libStream->readStream(entry._size); + + delete libStream; + return stream; +} + + +/** + * Reads in the index from a library file, and caches it's index for later use + */ +void Resources::loadLibraryIndex(const Common::String &libFilename, + Common::SeekableReadStream *stream) { + uint32 offset, nextOffset; + + // Create an index entry + _indexes[libFilename] = LibraryIndex(); + LibraryIndex &index = _indexes[libFilename]; + + // Read in the number of resources + stream->seek(4); + int count = stream->readUint16LE(); + + // Loop through reading in the entries + for (int idx = 0; idx < count; ++idx) { + // Read the name of the resource + char resName[13]; + stream->read(resName, 13); + resName[12] = '\0'; + + // Read the offset + offset = stream->readUint32LE(); + + if (idx == (count - 1)) { + nextOffset = stream->size(); + } else { + // Read the size by jumping forward to read the next entry's offset + stream->seek(13, SEEK_CUR); + nextOffset = stream->readUint32LE(); + stream->seek(-17, SEEK_CUR); + } + + // Add the entry to the index + index[resName] = LibraryEntry(idx, offset, nextOffset - offset); + } +} + +/** + * Returns the index of the last loaded resource in it's given library file. + * This will be used primarily when loading talk files, so the engine can + * update the given conversation number in the journal + */ +int Resources::resouceIndex() const { + return _resourceIndex; +} + +} // End of namespace Sherlock diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h new file mode 100644 index 0000000000..bfd2eb300c --- /dev/null +++ b/engines/sherlock/resources.h @@ -0,0 +1,86 @@ +/* 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 SHERLOCK_RESOURCES_H +#define SHERLOCK_RESOURCES_H + +#include "common/array.h" +#include "common/file.h" +#include "common/hashmap.h" +#include "common/hash-str.h" +#include "common/str.h" +#include "common/stream.h" + +namespace Sherlock { + +typedef Common::Array CacheEntry; +typedef Common::HashMap CacheHash; + +struct LibraryEntry { + uint32 _offset, _size; + int _index; + + LibraryEntry() : _index(0), _offset(0), _size(0) {} + LibraryEntry(int index, uint32 offset, uint32 size) : + _index(index), _offset(offset), _size(size) {} +}; +typedef Common::HashMap LibraryIndex; +typedef Common::HashMap LibraryIndexes; + +class SherlockEngine; + +class Cache { +private: + CacheHash _resources; +public: + Cache(); + + bool isCached(const Common::String &filename) const; + + void load(const Common::String &name); + + Common::SeekableReadStream *get(const Common::String &filename) const; +}; + +class Resources { +private: + Cache _cache; + LibraryIndexes _indexes; + int _resourceIndex; + + void loadLibraryIndex(const Common::String &libFilename, Common::SeekableReadStream *stream); +public: + Resources(); + + void addToCache(const Common::String &filename); + + Common::SeekableReadStream *load(const Common::String &filename); + + Common::SeekableReadStream *load(const Common::String &filename, const Common::String &libraryFile); + + int resouceIndex() const; +}; + + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/room.cpp b/engines/sherlock/room.cpp new file mode 100644 index 0000000000..246a316562 --- /dev/null +++ b/engines/sherlock/room.cpp @@ -0,0 +1,32 @@ +/* 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 "sherlock/room.h" + +namespace Sherlock { + +Rooms::Rooms() { + for (int roomNum = 0; roomNum < ROOMS_COUNT; ++roomNum) + Common::fill(&_stats[roomNum][0], &_stats[roomNum][9], false); +} + +} // End of namespace Sherlock diff --git a/engines/sherlock/room.h b/engines/sherlock/room.h new file mode 100644 index 0000000000..46755c1a10 --- /dev/null +++ b/engines/sherlock/room.h @@ -0,0 +1,102 @@ +/* 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 SHERLOCK_ROOM_H +#define SHERLOCK_ROOM_H + +#include "common/scummsys.h" +#include "sherlock/sprite.h" + +namespace Sherlock { + +#define ROOMS_COUNT 63 + +/* +struct RoomBounds { + int x, y, width, height; +}; + +struct BgshapeSub { + uint16 value; +}; + +struct Bgshape { + char name[12]; + char description[41]; + char *textBufferPtr; + byte *seqBufPtr; + Sprite *sprite; + SpriteFrame *spriteFrame; + byte byte05; + byte seqBigCountFlag; + int16 seqIndex; + int16 canimIndex; + int16 x, y; + int16 xIncr, yIncr, + uint16 status; + int16 x2, y2; + int16 width2, height2; + uint16 word02; + uint16 word03; + byte flag; + byte itemValue; + uint16 word01; + uint16 word05; + uint16 stringIndex; + int16 width, height; + uint16 word04; + byte flagsAndIndex; + uint16 frameCount; + byte spriteFlags; + char string1[50]; + byte byte07; + byte byte01; + byte byte02; + int16 boundsX, boundsY; + byte direction; + byte animIndex; + char string2[50]; + byte byte06; + byte seqByte; + uint16 textBufferOfs; + byte byte03; + uint16 framesCopyCount; + byte byte08; + char string3[51]; + uint16 word06; + uint16 word07; + uint16 word08; + uint16 word09; + BgshapeSub subItems[4]; +}; +*/ +class Rooms { +public: + bool _stats[ROOMS_COUNT][9]; + bool _savedStats[ROOMS_COUNT][9]; +public: + Rooms(); +}; + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp new file mode 100644 index 0000000000..11b78946f9 --- /dev/null +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -0,0 +1,40 @@ +/* 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 "sherlock/scalpel/scalpel.h" + +namespace Sherlock { + +namespace Scalpel { + +/** + * Initialises game flags + */ +void ScalpelEngine::initFlags() { + _flags.resize(100 * 8); + _flags[3] = true; // Turn on Alley + _flags[39] = true; // Turn on Baker Street +} + +} // End of namespace Scalpel + +} // End of namespace Scalpel diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h new file mode 100644 index 0000000000..e9f9aa05a2 --- /dev/null +++ b/engines/sherlock/scalpel/scalpel.h @@ -0,0 +1,45 @@ +/* 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 SHERLOCK_SCALPEL_H +#define SHERLOCK_SCALPEL_H + +#include "sherlock/sherlock.h" + +namespace Sherlock { + +namespace Scalpel { + +class ScalpelEngine : public SherlockEngine { +public: + ScalpelEngine(OSystem *syst, const SherlockGameDescription *gameDesc) : + SherlockEngine(syst, gameDesc) {} + virtual ~ScalpelEngine() {} + + virtual void initFlags(); +}; + +} // End of namespace Scalpel + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp new file mode 100644 index 0000000000..a6ae6e215c --- /dev/null +++ b/engines/sherlock/sherlock.cpp @@ -0,0 +1,81 @@ +/* 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 "sherlock/sherlock.h" +#include "sherlock/graphics.h" +#include "common/scummsys.h" +#include "common/debug-channels.h" +#include "engines/util.h" + +namespace Sherlock { + +SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc) : + Engine(syst), _gameDescription(gameDesc) { + _journal = nullptr; + _res = nullptr; + _rooms = nullptr; + _talk = nullptr; +} + + +SherlockEngine::~SherlockEngine() { + delete _journal; + delete _res; + delete _rooms; + delete _talk; +} + +void SherlockEngine::initialize() { + initGraphics(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT, false); + + DebugMan.addDebugChannel(kDebugScript, "scripts", "Script debug level"); + + /* + int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); + bool native_mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32")); + + MidiDriver *driver = MidiDriver::createMidi(midiDriver); + if (native_mt32) + driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); + + _midi = new MidiPlayer(this, driver); + _midi->setGM(true); + _midi->setNativeMT32(native_mt32); + */ + + _journal = new Journal(); + _res = new Resources(); + _rooms = new Rooms(); + _talk = new Talk(); + + initFlags(); +} + +Common::Error SherlockEngine::run() { + initialize(); + + // TODO: The rest of the game + + return Common::kNoError; +} + +} // End of namespace Comet diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h new file mode 100644 index 0000000000..a68650c0a9 --- /dev/null +++ b/engines/sherlock/sherlock.h @@ -0,0 +1,91 @@ +/* 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 SHERLOCK_HOLMES_H +#define SHERLOCK_HOLMES_H + +#include "common/scummsys.h" +#include "common/array.h" +#include "common/endian.h" +#include "common/util.h" +#include "common/savefile.h" +#include "common/hash-str.h" +#include "engines/engine.h" +#include "sherlock/journal.h" +#include "sherlock/resources.h" +#include "sherlock/room.h" +#include "sherlock/talk.h" + +namespace Sherlock { + +enum { + kFileTypeHash +}; + +enum { + kDebugScript = 1 << 0 +}; + +enum { + GType_SerratedScalpel = 0, + GType_RoseTattoo = 1 +}; + +#define SHERLOCK_SCREEN_WIDTH 320 +#define SHERLOCK_SCREEN_HEIGHT 200 + +struct SherlockGameDescription; + +class Resource; + +class SherlockEngine : public Engine { +private: + bool detectGame(); + + void initialize(); +public: + const SherlockGameDescription *_gameDescription; + Journal *_journal; + Resources *_res; + Rooms *_rooms; + Talk *_talk; + Common::Array _flags; +public: + SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc); + virtual ~SherlockEngine(); + + virtual Common::Error run(); + + virtual void initFlags() = 0; + + int getGameType() const; + uint32 getGameID() const; + uint32 getGameFeatures() const; + Common::Language getLanguage() const; + Common::Platform getPlatform() const; + + Common::String getGameFile(int fileType); +}; + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h new file mode 100644 index 0000000000..f3b34345ef --- /dev/null +++ b/engines/sherlock/sound.h @@ -0,0 +1,39 @@ +/* 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 SHERLOCK_SOUND_H +#define SHERLOCK_SOUND_H + +namespace Sherlock { + +class Sound { +public + void playSound(const char *name); + void cacheSound(const char *name, int index); + void playCachedSound(int index); + void clearCache(); + +}; + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/sprite.cpp b/engines/sherlock/sprite.cpp new file mode 100644 index 0000000000..7aa2fdc71b --- /dev/null +++ b/engines/sherlock/sprite.cpp @@ -0,0 +1,142 @@ +/* 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 "sherlock/sprite.h" +#include "common/debug.h" + +namespace Sherlock { + +/* +struct SpriteFrame { + byte *data; + int width, height; + uint16 flags; + int xofs, yofs; + byte rleMarker; +}; +*/ + +Sprite::Sprite(Common::SeekableReadStream &stream) { + load(stream); +} + +Sprite::~Sprite() { +} + +int Sprite::getFrameCount() { + return _frames.size(); +} + +SpriteFrame *Sprite::getFrame(int index) { + return _frames[index]; +} + +void Sprite::load(Common::SeekableReadStream &stream) { + + while (!stream.eos()) { + + debug("frameNum = %d\n", _frames.size()); + + SpriteFrame *spriteFrame = new SpriteFrame(); + + uint32 startOfs = stream.pos(); + + debug("startOfs = %08X\n", startOfs); + + spriteFrame->frame = NULL; + spriteFrame->width = stream.readUint16LE() + 1; + spriteFrame->height = stream.readUint16LE() + 1; + spriteFrame->flags = stream.readUint16LE(); + stream.readUint16LE(); + + debug("width = %d; height = %d; flags = %04X\n", spriteFrame->width, spriteFrame->height, spriteFrame->flags); + + if (spriteFrame->flags & 0xFF) { + spriteFrame->size = (spriteFrame->width * spriteFrame->height) / 2; + } else if (spriteFrame->flags & 0x0100) { + // this size includes the header size, which we subtract + spriteFrame->size = stream.readUint16LE() - 11; + spriteFrame->rleMarker = stream.readByte(); + } else { + spriteFrame->size = spriteFrame->width * spriteFrame->height; + } + + spriteFrame->data = new byte[spriteFrame->size]; + stream.read(spriteFrame->data, spriteFrame->size); + + decompressFrame(spriteFrame); + + /* + debug("size = %d (%08X)\n", spriteFrame->size, spriteFrame->size); + if (spriteFrame->frame) { + char fn[128]; + sndebug(fn, 128, "%04d.spr", _frames.size()); + FILE *x = fopen(fn, "wb"); + fwrite(spriteFrame->frame->pixels, spriteFrame->frame->w * spriteFrame->frame->h, 1, x); + fclose(x); + } + */ + + _frames.push_back(spriteFrame); + + } + + // debug("Done: %08X\n", stream.pos()); fflush(stdout); + +} + +void Sprite::decompressFrame(SpriteFrame *frame) { + + frame->frame = new Graphics::Surface(); + frame->frame->create(frame->width, frame->height, Graphics::PixelFormat::createFormatCLUT8()); + + if (frame->flags & 0xFF) { + debug("Sprite::decompressFrame() 4-bits/pixel\n"); + debug("TODO\n"); + } else if (frame->flags & 0x0100) { + debug("Sprite::decompressFrame() RLE-compressed; rleMarker = %02X\n", frame->rleMarker); + const byte *src = frame->data; + byte *dst = (byte *)frame->frame->getPixels(); + for (uint16 h = 0; h < frame->height; h++) { + int16 w = frame->width; + while (w > 0) { + if (*src == frame->rleMarker) { + byte rleColor = src[1]; + byte rleCount = src[2]; + src += 3; + w -= rleCount; + while (rleCount--) + *dst++ = rleColor; + } else { + *dst++ = *src++; + w--; + } + } + } + } else { + debug("Sprite::decompressFrame() Uncompressed\n"); + memcpy(frame->data, frame->frame->getPixels(), frame->width * frame->height); + } + +} + +} // End of namespace Sherlock diff --git a/engines/sherlock/sprite.h b/engines/sherlock/sprite.h new file mode 100644 index 0000000000..f56ab588bb --- /dev/null +++ b/engines/sherlock/sprite.h @@ -0,0 +1,56 @@ +/* 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 SHERLOCK_SPRITE_H +#define SHERLOCK_SPRITE_H + +#include "common/stream.h" +#include "common/array.h" +#include "graphics/surface.h" + +namespace Sherlock { + +struct SpriteFrame { + byte *data; + uint32 size; + uint16 width, height; + uint16 flags; + int xofs, yofs; + byte rleMarker; + Graphics::Surface *frame; +}; + +class Sprite { +public: + Sprite(Common::SeekableReadStream &stream); + ~Sprite(); + int getFrameCount(); + SpriteFrame *getFrame(int index); +protected: + Common::Array _frames; + void load(Common::SeekableReadStream &stream); + void decompressFrame(SpriteFrame *frame); +}; + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp new file mode 100644 index 0000000000..3122aff95f --- /dev/null +++ b/engines/sherlock/talk.cpp @@ -0,0 +1,30 @@ +/* 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 "sherlock/talk.h" + +namespace Sherlock { + +Talk::Talk() { +} + +} // End of namespace Sherlock diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h new file mode 100644 index 0000000000..6ffbcdd8d4 --- /dev/null +++ b/engines/sherlock/talk.h @@ -0,0 +1,49 @@ +/* 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 SHERLOCK_TALK_H +#define SHERLOCK_TALK_H + +#include "common/scummsys.h" +#include "common/array.h" + +namespace Sherlock { + +struct TalkHistoryEntry { +private: + int _data[2]; +public: + TalkHistoryEntry() { _data[0] = _data[1] = 0; } + + int &operator[](int idx) { return _data[idx]; } +}; + +class Talk { +public: + Common::Array _history; +public: + Talk(); +}; + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/tattoo/tattoo.cpp b/engines/sherlock/tattoo/tattoo.cpp new file mode 100644 index 0000000000..bed6edb3d4 --- /dev/null +++ b/engines/sherlock/tattoo/tattoo.cpp @@ -0,0 +1,38 @@ +/* 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 "sherlock/tattoo/tattoo.h" + +namespace Sherlock { + +namespace Tattoo { + +/** + * Initialises game flags + */ +void TattooEngine::initFlags() { + _flags.resize(100 * 8); +} + +} // End of namespace Tattoo + +} // End of namespace Scalpel diff --git a/engines/sherlock/tattoo/tattoo.h b/engines/sherlock/tattoo/tattoo.h new file mode 100644 index 0000000000..e2977983f1 --- /dev/null +++ b/engines/sherlock/tattoo/tattoo.h @@ -0,0 +1,45 @@ +/* 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 SHERLOCK_TATTOO_H +#define SHERLOCK_TATTOO_H + +#include "sherlock/sherlock.h" + +namespace Sherlock { + +namespace Tattoo { + +class TattooEngine : public SherlockEngine { +public: + TattooEngine(OSystem *syst, const SherlockGameDescription *gameDesc) : + SherlockEngine(syst, gameDesc) {} + virtual ~TattooEngine() {} + + virtual void initFlags(); +}; + +} // End of namespace Tattoo + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/vdaplayer.h b/engines/sherlock/vdaplayer.h new file mode 100644 index 0000000000..9b755606d5 --- /dev/null +++ b/engines/sherlock/vdaplayer.h @@ -0,0 +1,34 @@ +/* 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 SHERLOCK_VDAPLAYER_H +#define SHERLOCK_VDAPLAYER_H + +namespace Sherlock { + +class VdaPlayer { + +}; + +} // End of namespace Sherlock + +#endif -- cgit v1.2.3 From eaab373a9687c6d6d3be3983bb77da5a69897a24 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 15 Mar 2015 17:25:21 -0400 Subject: SHERLOCK: Added skeleton Screen class --- engines/sherlock/graphics.cpp | 21 +++++++++++++++++++++ engines/sherlock/graphics.h | 14 ++++++++++++++ engines/sherlock/sherlock.cpp | 3 +++ engines/sherlock/sherlock.h | 2 ++ 4 files changed, 40 insertions(+) diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index f4a5bf1864..695635d2ca 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -21,6 +21,8 @@ */ #include "sherlock/graphics.h" +#include "sherlock/sherlock.h" +#include "common/system.h" namespace Sherlock { @@ -41,5 +43,24 @@ void Surface::drawSprite(int x, int y, SpriteFrame *spriteFrame, bool flipped, b } +/*----------------------------------------------------------------*/ + +Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), _vm(vm) { + setFont(1); +} + +void Screen::setFont(int fontNumber) { + _fontNumber = fontNumber; + Common::String fname = Common::String::format("FONT%d.VGS", fontNumber); + Common::SeekableReadStream *stream = _vm->_res->load(fname); + + debug("TODO: Loading font %s, size - %d", fname.c_str(), stream->size()); + + delete stream; +} + +void Screen::update() { + g_system->updateScreen(); +} } // End of namespace Sherlock diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index 64518a78c6..fe03e7155d 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -30,6 +30,8 @@ namespace Sherlock { +class SherlockEngine; + class Surface : public Graphics::Surface { public: Surface(uint16 width, uint16 height); @@ -38,6 +40,18 @@ public: void drawSprite(int x, int y, SpriteFrame *spriteFrame, bool flipped = false, bool altFlag = false); }; +class Screen : public Surface { +private: + SherlockEngine *_vm; + int _fontNumber; +public: + Screen(SherlockEngine *vm); + + void setFont(int fontNumber); + + void update(); +}; + } // End of namespace Sherlock #endif diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index a6ae6e215c..0d55e0ba8d 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -33,6 +33,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _journal = nullptr; _res = nullptr; _rooms = nullptr; + _screen = nullptr; _talk = nullptr; } @@ -41,6 +42,7 @@ SherlockEngine::~SherlockEngine() { delete _journal; delete _res; delete _rooms; + delete _screen; delete _talk; } @@ -65,6 +67,7 @@ void SherlockEngine::initialize() { _journal = new Journal(); _res = new Resources(); _rooms = new Rooms(); + _screen = new Screen(this); _talk = new Talk(); initFlags(); diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index a68650c0a9..4c5f86dd09 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -30,6 +30,7 @@ #include "common/savefile.h" #include "common/hash-str.h" #include "engines/engine.h" +#include "sherlock/graphics.h" #include "sherlock/journal.h" #include "sherlock/resources.h" #include "sherlock/room.h" @@ -67,6 +68,7 @@ public: Journal *_journal; Resources *_res; Rooms *_rooms; + Screen *_screen; Talk *_talk; Common::Array _flags; public: -- cgit v1.2.3 From a6db2fb281fb5842be2d8fc0621922e70ad9668c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 15 Mar 2015 17:50:10 -0400 Subject: SHERLOCK: Further game setup --- engines/sherlock/room.cpp | 2 ++ engines/sherlock/room.h | 1 + engines/sherlock/scalpel/scalpel.cpp | 8 ++++++-- engines/sherlock/scalpel/scalpel.h | 4 ++-- engines/sherlock/sherlock.cpp | 2 -- engines/sherlock/sherlock.h | 7 ++----- engines/sherlock/tattoo/tattoo.cpp | 7 ------- engines/sherlock/tattoo/tattoo.h | 2 -- 8 files changed, 13 insertions(+), 20 deletions(-) diff --git a/engines/sherlock/room.cpp b/engines/sherlock/room.cpp index 246a316562..9926899953 100644 --- a/engines/sherlock/room.cpp +++ b/engines/sherlock/room.cpp @@ -27,6 +27,8 @@ namespace Sherlock { Rooms::Rooms() { for (int roomNum = 0; roomNum < ROOMS_COUNT; ++roomNum) Common::fill(&_stats[roomNum][0], &_stats[roomNum][9], false); + + _goToRoom = -1; } } // End of namespace Sherlock diff --git a/engines/sherlock/room.h b/engines/sherlock/room.h index 46755c1a10..75800b623a 100644 --- a/engines/sherlock/room.h +++ b/engines/sherlock/room.h @@ -93,6 +93,7 @@ class Rooms { public: bool _stats[ROOMS_COUNT][9]; bool _savedStats[ROOMS_COUNT][9]; + int _goToRoom; public: Rooms(); }; diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 11b78946f9..bd8c96f253 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -27,14 +27,18 @@ namespace Sherlock { namespace Scalpel { /** - * Initialises game flags + * Game initialization */ -void ScalpelEngine::initFlags() { +void ScalpelEngine::initialize() { _flags.resize(100 * 8); _flags[3] = true; // Turn on Alley _flags[39] = true; // Turn on Baker Street + + // Starting room + _rooms->_goToRoom = 4; } + } // End of namespace Scalpel } // End of namespace Scalpel diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h index e9f9aa05a2..9001c20456 100644 --- a/engines/sherlock/scalpel/scalpel.h +++ b/engines/sherlock/scalpel/scalpel.h @@ -30,12 +30,12 @@ namespace Sherlock { namespace Scalpel { class ScalpelEngine : public SherlockEngine { +protected: + virtual void initialize(); public: ScalpelEngine(OSystem *syst, const SherlockGameDescription *gameDesc) : SherlockEngine(syst, gameDesc) {} virtual ~ScalpelEngine() {} - - virtual void initFlags(); }; } // End of namespace Scalpel diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 0d55e0ba8d..13731e2fd8 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -69,8 +69,6 @@ void SherlockEngine::initialize() { _rooms = new Rooms(); _screen = new Screen(this); _talk = new Talk(); - - initFlags(); } Common::Error SherlockEngine::run() { diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 4c5f86dd09..172c940c34 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -60,9 +60,8 @@ class Resource; class SherlockEngine : public Engine { private: - bool detectGame(); - - void initialize(); +protected: + virtual void initialize(); public: const SherlockGameDescription *_gameDescription; Journal *_journal; @@ -77,8 +76,6 @@ public: virtual Common::Error run(); - virtual void initFlags() = 0; - int getGameType() const; uint32 getGameID() const; uint32 getGameFeatures() const; diff --git a/engines/sherlock/tattoo/tattoo.cpp b/engines/sherlock/tattoo/tattoo.cpp index bed6edb3d4..57ca5c6e29 100644 --- a/engines/sherlock/tattoo/tattoo.cpp +++ b/engines/sherlock/tattoo/tattoo.cpp @@ -26,13 +26,6 @@ namespace Sherlock { namespace Tattoo { -/** - * Initialises game flags - */ -void TattooEngine::initFlags() { - _flags.resize(100 * 8); -} - } // End of namespace Tattoo } // End of namespace Scalpel diff --git a/engines/sherlock/tattoo/tattoo.h b/engines/sherlock/tattoo/tattoo.h index e2977983f1..f06fa1532d 100644 --- a/engines/sherlock/tattoo/tattoo.h +++ b/engines/sherlock/tattoo/tattoo.h @@ -34,8 +34,6 @@ public: TattooEngine(OSystem *syst, const SherlockGameDescription *gameDesc) : SherlockEngine(syst, gameDesc) {} virtual ~TattooEngine() {} - - virtual void initFlags(); }; } // End of namespace Tattoo -- cgit v1.2.3 From 1452c18ffb21da0d97725c7c982b25992bd75fe8 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 15 Mar 2015 18:42:24 -0400 Subject: SHERLOCK: Added events manager and debugger classes --- engines/sherlock/debugger.cpp | 59 +++++++++++++ engines/sherlock/debugger.h | 45 ++++++++++ engines/sherlock/events.cpp | 167 +++++++++++++++++++++++++++++++++++ engines/sherlock/events.h | 82 +++++++++++++++++ engines/sherlock/graphics.cpp | 4 +- engines/sherlock/graphics.h | 1 + engines/sherlock/module.mk | 2 + engines/sherlock/scalpel/scalpel.cpp | 9 ++ engines/sherlock/scalpel/scalpel.h | 2 + engines/sherlock/sherlock.cpp | 7 +- engines/sherlock/sherlock.h | 4 + engines/sherlock/tattoo/tattoo.cpp | 4 + engines/sherlock/tattoo/tattoo.h | 2 + 13 files changed, 386 insertions(+), 2 deletions(-) create mode 100644 engines/sherlock/debugger.cpp create mode 100644 engines/sherlock/debugger.h create mode 100644 engines/sherlock/events.cpp create mode 100644 engines/sherlock/events.h diff --git a/engines/sherlock/debugger.cpp b/engines/sherlock/debugger.cpp new file mode 100644 index 0000000000..50300322ef --- /dev/null +++ b/engines/sherlock/debugger.cpp @@ -0,0 +1,59 @@ +/* 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 "sherlock/debugger.h" +#include "sherlock/sherlock.h" + +namespace Sherlock { + +Debugger::Debugger(SherlockEngine *vm) : GUI::Debugger(), _vm(vm) { + registerCmd("continue", WRAP_METHOD(Debugger, cmdExit)); + registerCmd("scene", WRAP_METHOD(Debugger, cmd_scene)); +} + +static int strToInt(const char *s) { + if (!*s) + // No string at all + return 0; + else if (toupper(s[strlen(s) - 1]) != 'H') + // Standard decimal string + return atoi(s); + + // Hexadecimal string + uint tmp = 0; + int read = sscanf(s, "%xh", &tmp); + if (read < 1) + error("strToInt failed on string \"%s\"", s); + return (int)tmp; +} + +bool Debugger::cmd_scene(int argc, const char **argv) { + if (argc != 2) { + debugPrintf("Format: scene \n"); + return true; + } else { + _vm->_rooms->_goToRoom = strToInt(argv[1]); + return false; + } +} + +} // End of namespace Sherlock diff --git a/engines/sherlock/debugger.h b/engines/sherlock/debugger.h new file mode 100644 index 0000000000..8c7291c9e6 --- /dev/null +++ b/engines/sherlock/debugger.h @@ -0,0 +1,45 @@ +/* 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 SHERLOCK_DEBUGGER_H +#define SHERLOCK_DEBUGGER_H + +#include "common/scummsys.h" +#include "gui/debugger.h" + +namespace Sherlock { + +class SherlockEngine; + +class Debugger : public GUI::Debugger { +private: + SherlockEngine *_vm; +protected: + bool cmd_scene(int argc, const char **argv); +public: + Debugger(SherlockEngine *vm); + virtual ~Debugger() {} +}; + +} // End of namespace Sherlock + +#endif /* SHERLOCK_DEBUGGER_H */ diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp new file mode 100644 index 0000000000..7e62dc075b --- /dev/null +++ b/engines/sherlock/events.cpp @@ -0,0 +1,167 @@ +/* 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 "common/scummsys.h" +#include "common/events.h" +#include "common/system.h" +#include "engines/util.h" +#include "graphics/cursorman.h" +#include "sherlock/sherlock.h" +#include "sherlock/events.h" + +namespace Sherlock { + +EventsManager::EventsManager(SherlockEngine *vm) { + _vm = vm; + _cursorId = CURSOR_NONE; + _frameCounter = 1; + _priorFrameTime = 0; + _mouseClicked = false; + _mouseButtons = 0; +} + +EventsManager::~EventsManager() { +} + +/** + * Set the cursor to show + */ +void EventsManager::setCursor(CursorType cursorId) { + _cursorId = cursorId; + + // TODO: Cursor handling +} + +/** + * Show the mouse cursor + */ +void EventsManager::showCursor() { + CursorMan.showMouse(true); +} + +/** + * Hide the mouse cursor + */ +void EventsManager::hideCursor() { + CursorMan.showMouse(false); +} + +/** + * Returns true if the mouse cursor is visible + */ +bool EventsManager::isCursorVisible() { + return CursorMan.isVisible(); +} + +void EventsManager::pollEvents() { + checkForNextFrameCounter(); + + Common::Event event; + while (g_system->getEventManager()->pollEvent(event)) { + // Handle keypress + switch (event.type) { + case Common::EVENT_QUIT: + case Common::EVENT_RTL: + return; + + case Common::EVENT_KEYDOWN: + // Check for debugger + if (event.kbd.keycode == Common::KEYCODE_d && (event.kbd.flags & Common::KBD_CTRL)) { + // Attach to the debugger + _vm->_debugger->attach(); + _vm->_debugger->onFrame(); + } else { + _pendingKeys.push(event.kbd); + } + return; + case Common::EVENT_KEYUP: + return; + case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_RBUTTONDOWN: + _mouseClicked = true; + return; + case Common::EVENT_LBUTTONUP: + case Common::EVENT_RBUTTONUP: + _mouseClicked = false; + return; + case Common::EVENT_MOUSEMOVE: + _mousePos = event.mouse; + break; + default: + break; + } + } +} + +bool EventsManager::checkForNextFrameCounter() { + // Check for next game frame + uint32 milli = g_system->getMillis(); + if ((milli - _priorFrameTime) >= GAME_FRAME_TIME) { + ++_frameCounter; + _priorFrameTime = milli; + + // Give time to the debugger + _vm->_debugger->onFrame(); + + // Display the frame + _vm->_screen->update(); + + // Signal the ScummVM debugger + _vm->_debugger->onFrame(); + + return true; + } + + return false; +} + +void EventsManager::delay(int cycles) { + uint32 totalMilli = cycles * 1000 / GAME_FRAME_RATE; + uint32 delayEnd = g_system->getMillis() + totalMilli; + + while (!_vm->shouldQuit() && g_system->getMillis() < delayEnd) { + g_system->delayMillis(10); + + pollEvents(); + } +} + +void EventsManager::waitForNextFrame() { + _mouseClicked = false; + _mouseButtons = 0; + + bool mouseClicked = false; + int mouseButtons = 0; + + uint32 frameCtr = getFrameCounter(); + while (!_vm->shouldQuit() && frameCtr == _frameCounter) { + delay(1); + + mouseClicked |= _mouseClicked; + mouseButtons |= _mouseButtons; + } + + _mouseClicked = mouseClicked; + _mouseButtons = mouseButtons; +} + +} // End of namespace MADS diff --git a/engines/sherlock/events.h b/engines/sherlock/events.h new file mode 100644 index 0000000000..4ba30e0bdf --- /dev/null +++ b/engines/sherlock/events.h @@ -0,0 +1,82 @@ +/* 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 SHERLOCK_EVENTS_H +#define SHERLOCK_EVENTS_H + +#include "common/scummsys.h" +#include "common/events.h" +#include "common/stack.h" + +namespace Sherlock { + +enum CursorType { CURSOR_NONE = 0 }; + +#define GAME_FRAME_RATE 50 +#define GAME_FRAME_TIME (1000 / GAME_FRAME_RATE) + +class SherlockEngine; + +class EventsManager { +private: + SherlockEngine *_vm; + uint32 _frameCounter; + uint32 _priorFrameTime; + Common::Point _mousePos; + + bool checkForNextFrameCounter(); +public: + CursorType _cursorId; + byte _mouseButtons; + bool _mouseClicked; + Common::Stack _pendingKeys; +public: + EventsManager(SherlockEngine *vm); + ~EventsManager(); + + void setCursor(CursorType cursorId); + + void showCursor(); + + void hideCursor(); + + bool isCursorVisible(); + + void pollEvents(); + + Common::Point mousePos() const { return _mousePos; } + + uint32 getFrameCounter() const { return _frameCounter; } + + bool isKeyPressed() const { return !_pendingKeys.empty(); } + + Common::KeyState getKey() { return _pendingKeys.pop(); } + + void delay(int amount); + + void waitForNextFrame(); + +}; + +} // End of namespace Sherlock + +#endif /* SHERLOCK_EVENTS_H */ diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index 695635d2ca..5c6c94606e 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -45,7 +45,9 @@ void Surface::drawSprite(int x, int y, SpriteFrame *spriteFrame, bool flipped, b /*----------------------------------------------------------------*/ -Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), _vm(vm) { +Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), _vm(vm), + _backBuffer1(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), + _backBuffer2(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT) { setFont(1); } diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index fe03e7155d..801b1747ee 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -44,6 +44,7 @@ class Screen : public Surface { private: SherlockEngine *_vm; int _fontNumber; + Surface _backBuffer1, _backBuffer2; public: Screen(SherlockEngine *vm); diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk index 1dfcb3a5af..19ad039262 100644 --- a/engines/sherlock/module.mk +++ b/engines/sherlock/module.mk @@ -4,7 +4,9 @@ MODULE_OBJS = \ scalpel/scalpel.o \ tattoo/tattoo.o \ decompress.o \ + debugger.o \ detection.o \ + events.o \ graphics.o \ journal.o \ resources.o \ diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index bd8c96f253..1eaf7c91ee 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -30,6 +30,8 @@ namespace Scalpel { * Game initialization */ void ScalpelEngine::initialize() { + SherlockEngine::initialize(); + _flags.resize(100 * 8); _flags[3] = true; // Turn on Alley _flags[39] = true; // Turn on Baker Street @@ -38,6 +40,13 @@ void ScalpelEngine::initialize() { _rooms->_goToRoom = 4; } +/** + * Show the opening sequence + */ +void ScalpelEngine::showOpening() { + // TODO +} + } // End of namespace Scalpel diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h index 9001c20456..6016984e45 100644 --- a/engines/sherlock/scalpel/scalpel.h +++ b/engines/sherlock/scalpel/scalpel.h @@ -32,6 +32,8 @@ namespace Scalpel { class ScalpelEngine : public SherlockEngine { protected: virtual void initialize(); + + virtual void showOpening(); public: ScalpelEngine(OSystem *syst, const SherlockGameDescription *gameDesc) : SherlockEngine(syst, gameDesc) {} diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 13731e2fd8..cfbbacccf7 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -30,6 +30,7 @@ namespace Sherlock { SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) { + _debugger = nullptr; _journal = nullptr; _res = nullptr; _rooms = nullptr; @@ -39,6 +40,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam SherlockEngine::~SherlockEngine() { + delete _debugger; delete _journal; delete _res; delete _rooms; @@ -64,6 +66,7 @@ void SherlockEngine::initialize() { _midi->setNativeMT32(native_mt32); */ + _debugger = new Debugger(this); _journal = new Journal(); _res = new Resources(); _rooms = new Rooms(); @@ -74,7 +77,9 @@ void SherlockEngine::initialize() { Common::Error SherlockEngine::run() { initialize(); - // TODO: The rest of the game + showOpening(); + + // TODO: Rest of game return Common::kNoError; } diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 172c940c34..781851db71 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -30,6 +30,7 @@ #include "common/savefile.h" #include "common/hash-str.h" #include "engines/engine.h" +#include "sherlock/debugger.h" #include "sherlock/graphics.h" #include "sherlock/journal.h" #include "sherlock/resources.h" @@ -62,8 +63,11 @@ class SherlockEngine : public Engine { private: protected: virtual void initialize(); + + virtual void showOpening() = 0; public: const SherlockGameDescription *_gameDescription; + Debugger *_debugger; Journal *_journal; Resources *_res; Rooms *_rooms; diff --git a/engines/sherlock/tattoo/tattoo.cpp b/engines/sherlock/tattoo/tattoo.cpp index 57ca5c6e29..b2b45bc310 100644 --- a/engines/sherlock/tattoo/tattoo.cpp +++ b/engines/sherlock/tattoo/tattoo.cpp @@ -26,6 +26,10 @@ namespace Sherlock { namespace Tattoo { +void TattooEngine::showOpening() { + // TODO +} + } // End of namespace Tattoo } // End of namespace Scalpel diff --git a/engines/sherlock/tattoo/tattoo.h b/engines/sherlock/tattoo/tattoo.h index f06fa1532d..6d3ec33967 100644 --- a/engines/sherlock/tattoo/tattoo.h +++ b/engines/sherlock/tattoo/tattoo.h @@ -30,6 +30,8 @@ namespace Sherlock { namespace Tattoo { class TattooEngine : public SherlockEngine { +protected: + virtual void showOpening(); public: TattooEngine(OSystem *syst, const SherlockGameDescription *gameDesc) : SherlockEngine(syst, gameDesc) {} -- cgit v1.2.3 From 92c55e2bb192785e4587e143c9c367213f30233c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 15 Mar 2015 21:25:07 -0400 Subject: SHERLOCK: Beginning of animation player --- engines/sherlock/animation.cpp | 124 +++++++++++++++++++++++++++++++++++ engines/sherlock/animation.h | 50 ++++++++++++++ engines/sherlock/events.cpp | 20 ++++++ engines/sherlock/events.h | 2 + engines/sherlock/graphics.h | 2 + engines/sherlock/module.mk | 2 + engines/sherlock/scalpel/scalpel.cpp | 34 ++++++++++ engines/sherlock/scalpel/scalpel.h | 5 ++ engines/sherlock/sherlock.cpp | 8 +++ engines/sherlock/sherlock.h | 6 ++ engines/sherlock/sound.cpp | 55 ++++++++++++++++ engines/sherlock/sound.h | 17 ++++- engines/sherlock/vdaplayer.h | 34 ---------- 13 files changed, 322 insertions(+), 37 deletions(-) create mode 100644 engines/sherlock/animation.cpp create mode 100644 engines/sherlock/animation.h create mode 100644 engines/sherlock/sound.cpp delete mode 100644 engines/sherlock/vdaplayer.h diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp new file mode 100644 index 0000000000..52859ce5e4 --- /dev/null +++ b/engines/sherlock/animation.cpp @@ -0,0 +1,124 @@ +/* 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 "sherlock/animation.h" +#include "sherlock/sherlock.h" +#include "common/algorithm.h" + +namespace Sherlock { + +// The following are a list of filenames played in the prologue that have +// special effects associated with them at specific frames + +#define FRAMES_END 32000 +#define PROLOGUE_NAMES_COUNT 6 +#define TITLE_NAMES_COUNT 7 +static const char *const PROLOGUE_NAMES[6] = { + "subway1", "subway2", "finale2", "suicid", "coff3", "coff4" +}; +static const int PROLOGUE_FRAMES[6][9] = { + { 4, 26, 54, 72, 92, 134, FRAMES_END }, + { 2, 80, 95, 117, 166, FRAMES_END }, + { 1, FRAMES_END }, + { 42, FRAMES_END }, + { FRAMES_END }, + { FRAMES_END } +}; + +// Title animations file list +static const char *const TITLE_NAMES[7] = { + "27pro1", "14note", "coff1", "coff2", "coff3", "coff4", "14kick" +}; + +static const int TITLE_FRAMES[7][9] = { + { 29, 131, FRAMES_END }, + { 55, 80, 95, 117, 166, FRAMES_END }, + { 15, FRAMES_END }, + { 4, 37, 92, FRAMES_END }, + { 2, 43, FRAMES_END }, + { 2, FRAMES_END }, + { 10, 50, FRAMES_END } +}; + +static const int NO_FRAMES = FRAMES_END; + +Animation::Animation(SherlockEngine *vm): _vm(vm) { + _useEpilogue2 = false; +} + +void Animation::playPrologue(const Common::String &filename, int minDelay, int fade, + bool setPalette, int speed) { + // Check for any any sound frames for the given animation + const int *soundFrames = checkForSoundFrames(filename); + + // Strip any extension off of the passed filename and add .vdx suffix + Common::String baseName = filename; + const char *p = strchr(baseName.c_str(), '.'); + if (p) + baseName = Common::String(filename.c_str(), MIN(p - 1, baseName.c_str() + 7)); + + Common::String vdxName = baseName + ".vdx"; + + // Load the animation + Common::SeekableReadStream *stream; + if (!_titleOverride.empty()) + stream = _vm->_res->load(vdxName, _titleOverride); + else if (_useEpilogue2) + stream = _vm->_res->load(vdxName, "epilog2.lib"); + else + stream = _vm->_res->load(vdxName, "epilogoue.lib"); + int resoucreIndex = _vm->_res->resouceIndex(); + + // Load initial image + //Common::String vdaName = baseName + ".vda"; + // TODO + + + delete stream; +} + +/** + * Checks for whether an animation is being played that has associated sound + */ +const int *Animation::checkForSoundFrames(const Common::String &filename) { + const int *frames = &NO_FRAMES; + + if (!_soundOverride.empty()) { + for (int idx = 0; idx < PROLOGUE_NAMES_COUNT; ++idx) { + if (!scumm_stricmp(filename.c_str(), PROLOGUE_NAMES[idx])) { + frames = &PROLOGUE_FRAMES[idx][0]; + break; + } + } + } else { + for (int idx = 0; idx < TITLE_NAMES_COUNT; ++idx) { + if (!scumm_stricmp(filename.c_str(), TITLE_NAMES[idx])) { + frames = &TITLE_FRAMES[idx][0]; + break; + } + } + } + + return frames; +} + +} // End of namespace Sherlock diff --git a/engines/sherlock/animation.h b/engines/sherlock/animation.h new file mode 100644 index 0000000000..bf4429656e --- /dev/null +++ b/engines/sherlock/animation.h @@ -0,0 +1,50 @@ +/* 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 SHERLOCK_ANIMATION_H +#define SHERLOCK_ANIMATION_H + +#include "common/scummsys.h" +#include "common/str.h" + +namespace Sherlock { + +class SherlockEngine; + +class Animation { +private: + SherlockEngine *_vm; + + const int *checkForSoundFrames(const Common::String &filename); +public: + Common::String _soundOverride; + Common::String _titleOverride; + bool _useEpilogue2; +public: + Animation(SherlockEngine *vm); + + void playPrologue(const Common::String &filename, int minDelay, int fade, bool setPalette, int speed); +}; + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index 7e62dc075b..fdcf61e46f 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -72,6 +72,9 @@ bool EventsManager::isCursorVisible() { return CursorMan.isVisible(); } +/** + * Check for any pending events + */ void EventsManager::pollEvents() { checkForNextFrameCounter(); @@ -112,6 +115,9 @@ void EventsManager::pollEvents() { } } +/** + * Check whether it's time to display the next screen frame + */ bool EventsManager::checkForNextFrameCounter() { // Check for next game frame uint32 milli = g_system->getMillis(); @@ -134,6 +140,17 @@ bool EventsManager::checkForNextFrameCounter() { return false; } +/** + * Clear any current keypress or mouse click + */ +void EventsManager::clearEvents() { + _pendingKeys.clear(); + _mouseClicked = false; +} + +/** + * Delay for a given number of frames/cycles + */ void EventsManager::delay(int cycles) { uint32 totalMilli = cycles * 1000 / GAME_FRAME_RATE; uint32 delayEnd = g_system->getMillis() + totalMilli; @@ -145,6 +162,9 @@ void EventsManager::delay(int cycles) { } } +/** + * Wait for the next frame + */ void EventsManager::waitForNextFrame() { _mouseClicked = false; _mouseButtons = 0; diff --git a/engines/sherlock/events.h b/engines/sherlock/events.h index 4ba30e0bdf..26f4ddb2d5 100644 --- a/engines/sherlock/events.h +++ b/engines/sherlock/events.h @@ -71,6 +71,8 @@ public: Common::KeyState getKey() { return _pendingKeys.pop(); } + void clearEvents(); + void delay(int amount); void waitForNextFrame(); diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index 801b1747ee..97daaef6e3 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -30,6 +30,8 @@ namespace Sherlock { +#define PALETTE_SIZE 768 + class SherlockEngine; class Surface : public Graphics::Surface { diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk index 19ad039262..7009f49d3f 100644 --- a/engines/sherlock/module.mk +++ b/engines/sherlock/module.mk @@ -3,6 +3,7 @@ MODULE := engines/sherlock MODULE_OBJS = \ scalpel/scalpel.o \ tattoo/tattoo.o \ + animation.o \ decompress.o \ debugger.o \ detection.o \ @@ -12,6 +13,7 @@ MODULE_OBJS = \ resources.o \ room.o \ sherlock.o \ + sound.o \ sprite.o \ talk.o diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 1eaf7c91ee..72c5f1dcf3 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -21,6 +21,7 @@ */ #include "sherlock/scalpel/scalpel.h" +#include "sherlock/sherlock.h" namespace Sherlock { @@ -44,9 +45,42 @@ void ScalpelEngine::initialize() { * Show the opening sequence */ void ScalpelEngine::showOpening() { + if (!_events->isKeyPressed()) + showCityCutscene(); + if (!_events->isKeyPressed()) + showAlleyCutscene(); + if (!_events->isKeyPressed()) + showStreetCutscene(); + if (!_events->isKeyPressed()) + showOfficeCutscene(); + + _events->clearEvents(); + _sound->stopMusic(); +} + +void ScalpelEngine::showCityCutscene() { + byte palette[PALETTE_SIZE]; + + _sound->playMusic("prolog1.mus"); + _animation->_titleOverride = "title.lib"; + _animation->_soundOverride = "title.snd"; + _animation->playPrologue("26open1", 1, 255, true, 2); + // TODO } +void ScalpelEngine::showAlleyCutscene() { + +} + +void ScalpelEngine::showStreetCutscene() { + +} + +void ScalpelEngine::showOfficeCutscene() { + +} + } // End of namespace Scalpel diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h index 6016984e45..5da33e1d52 100644 --- a/engines/sherlock/scalpel/scalpel.h +++ b/engines/sherlock/scalpel/scalpel.h @@ -30,6 +30,11 @@ namespace Sherlock { namespace Scalpel { class ScalpelEngine : public SherlockEngine { +private: + void showCityCutscene(); + void showAlleyCutscene(); + void showStreetCutscene(); + void showOfficeCutscene(); protected: virtual void initialize(); diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index cfbbacccf7..a750741ec9 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -30,21 +30,27 @@ namespace Sherlock { SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) { + _animation = nullptr; _debugger = nullptr; + _events = nullptr; _journal = nullptr; _res = nullptr; _rooms = nullptr; _screen = nullptr; + _sound = nullptr; _talk = nullptr; } SherlockEngine::~SherlockEngine() { + delete _animation; delete _debugger; + delete _events; delete _journal; delete _res; delete _rooms; delete _screen; + delete _sound; delete _talk; } @@ -66,7 +72,9 @@ void SherlockEngine::initialize() { _midi->setNativeMT32(native_mt32); */ + _animation = new Animation(this); _debugger = new Debugger(this); + _events = new EventsManager(this); _journal = new Journal(); _res = new Resources(); _rooms = new Rooms(); diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 781851db71..88fbff74f9 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -30,11 +30,14 @@ #include "common/savefile.h" #include "common/hash-str.h" #include "engines/engine.h" +#include "sherlock/animation.h" #include "sherlock/debugger.h" +#include "sherlock/events.h" #include "sherlock/graphics.h" #include "sherlock/journal.h" #include "sherlock/resources.h" #include "sherlock/room.h" +#include "sherlock/sound.h" #include "sherlock/talk.h" namespace Sherlock { @@ -67,11 +70,14 @@ protected: virtual void showOpening() = 0; public: const SherlockGameDescription *_gameDescription; + Animation *_animation; Debugger *_debugger; + EventsManager *_events; Journal *_journal; Resources *_res; Rooms *_rooms; Screen *_screen; + Sound *_sound; Talk *_talk; Common::Array _flags; public: diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp new file mode 100644 index 0000000000..f16dd5a80d --- /dev/null +++ b/engines/sherlock/sound.cpp @@ -0,0 +1,55 @@ +/* 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 "sherlock/sound.h" + +namespace Sherlock { + +Sound::Sound(SherlockEngine *vm): _vm(vm) { +} + +void Sound::playSound(const Common::String &name) { + // TODO +} + +void Sound::cacheSound(const Common::String &name, int index) { + // TODO +} + +void Sound::playCachedSound(int index) { + // TODO +} + +void Sound::clearCache() { + // TODO +} + +void Sound::playMusic(const Common::String &name) { + // TODO +} + +void Sound::stopMusic() { + // TODO +} + + +} // End of namespace Sherlock diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index f3b34345ef..b1759a9c8e 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -23,15 +23,26 @@ #ifndef SHERLOCK_SOUND_H #define SHERLOCK_SOUND_H +#include "common/scummsys.h" +#include "common/str.h" + namespace Sherlock { +class SherlockEngine; + class Sound { -public - void playSound(const char *name); - void cacheSound(const char *name, int index); +private: + SherlockEngine *_vm; +public: + Sound(SherlockEngine *vm); + + void playSound(const Common::String &name); + void cacheSound(const Common::String &name, int index); void playCachedSound(int index); void clearCache(); + void playMusic(const Common::String &name); + void stopMusic(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/vdaplayer.h b/engines/sherlock/vdaplayer.h deleted file mode 100644 index 9b755606d5..0000000000 --- a/engines/sherlock/vdaplayer.h +++ /dev/null @@ -1,34 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef SHERLOCK_VDAPLAYER_H -#define SHERLOCK_VDAPLAYER_H - -namespace Sherlock { - -class VdaPlayer { - -}; - -} // End of namespace Sherlock - -#endif -- cgit v1.2.3 From 6cfb7169b94e0c3c665d7799584eb8e5a7f337b3 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 15 Mar 2015 23:16:38 -0400 Subject: SHERLOCK: Beginnings of sprite loading for animations --- engines/sherlock/animation.cpp | 17 +++--- engines/sherlock/animation.h | 3 - engines/sherlock/resources.cpp | 2 +- engines/sherlock/resources.h | 2 +- engines/sherlock/scalpel/scalpel.cpp | 4 +- engines/sherlock/sherlock.cpp | 1 + engines/sherlock/sherlock.h | 3 + engines/sherlock/sprite.cpp | 114 ++++++++++++----------------------- engines/sherlock/sprite.h | 27 ++++----- 9 files changed, 67 insertions(+), 106 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 52859ce5e4..3da0201a61 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -22,6 +22,7 @@ #include "sherlock/animation.h" #include "sherlock/sherlock.h" +#include "sherlock/sprite.h" #include "common/algorithm.h" namespace Sherlock { @@ -62,7 +63,6 @@ static const int TITLE_FRAMES[7][9] = { static const int NO_FRAMES = FRAMES_END; Animation::Animation(SherlockEngine *vm): _vm(vm) { - _useEpilogue2 = false; } void Animation::playPrologue(const Common::String &filename, int minDelay, int fade, @@ -80,16 +80,19 @@ void Animation::playPrologue(const Common::String &filename, int minDelay, int f // Load the animation Common::SeekableReadStream *stream; - if (!_titleOverride.empty()) - stream = _vm->_res->load(vdxName, _titleOverride); - else if (_useEpilogue2) + if (!_vm->_titleOverride.empty()) + stream = _vm->_res->load(vdxName, _vm->_titleOverride); + else if (_vm->_useEpilogue2) stream = _vm->_res->load(vdxName, "epilog2.lib"); else stream = _vm->_res->load(vdxName, "epilogoue.lib"); - int resoucreIndex = _vm->_res->resouceIndex(); + int resourceIndex = _vm->_res->resourceIndex(); // Load initial image - //Common::String vdaName = baseName + ".vda"; + Common::String vdaName = baseName + ".vda"; + Common::SeekableReadStream *vdaStream = _vm->_res->load(vdaName); + Sprite sprite(*vdaStream); + // TODO @@ -102,7 +105,7 @@ void Animation::playPrologue(const Common::String &filename, int minDelay, int f const int *Animation::checkForSoundFrames(const Common::String &filename) { const int *frames = &NO_FRAMES; - if (!_soundOverride.empty()) { + if (!_vm->_soundOverride.empty()) { for (int idx = 0; idx < PROLOGUE_NAMES_COUNT; ++idx) { if (!scumm_stricmp(filename.c_str(), PROLOGUE_NAMES[idx])) { frames = &PROLOGUE_FRAMES[idx][0]; diff --git a/engines/sherlock/animation.h b/engines/sherlock/animation.h index bf4429656e..14384cfa28 100644 --- a/engines/sherlock/animation.h +++ b/engines/sherlock/animation.h @@ -36,9 +36,6 @@ private: const int *checkForSoundFrames(const Common::String &filename); public: - Common::String _soundOverride; - Common::String _titleOverride; - bool _useEpilogue2; public: Animation(SherlockEngine *vm); diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index e59e65abff..47e2046084 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -212,7 +212,7 @@ void Resources::loadLibraryIndex(const Common::String &libFilename, * This will be used primarily when loading talk files, so the engine can * update the given conversation number in the journal */ -int Resources::resouceIndex() const { +int Resources::resourceIndex() const { return _resourceIndex; } diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h index bfd2eb300c..edb9bd8ba0 100644 --- a/engines/sherlock/resources.h +++ b/engines/sherlock/resources.h @@ -77,7 +77,7 @@ public: Common::SeekableReadStream *load(const Common::String &filename, const Common::String &libraryFile); - int resouceIndex() const; + int resourceIndex() const; }; diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 72c5f1dcf3..0b651bbb69 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -62,8 +62,8 @@ void ScalpelEngine::showCityCutscene() { byte palette[PALETTE_SIZE]; _sound->playMusic("prolog1.mus"); - _animation->_titleOverride = "title.lib"; - _animation->_soundOverride = "title.snd"; + _titleOverride = "title.lib"; + _soundOverride = "title.snd"; _animation->playPrologue("26open1", 1, 255, true, 2); // TODO diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index a750741ec9..cb0472feff 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -39,6 +39,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _screen = nullptr; _sound = nullptr; _talk = nullptr; + _useEpilogue2 = false; } diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 88fbff74f9..b04a14e8ac 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -80,6 +80,9 @@ public: Sound *_sound; Talk *_talk; Common::Array _flags; + Common::String _soundOverride; + Common::String _titleOverride; + bool _useEpilogue2; public: SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc); virtual ~SherlockEngine(); diff --git a/engines/sherlock/sprite.cpp b/engines/sherlock/sprite.cpp index 7aa2fdc71b..f686f0b27e 100644 --- a/engines/sherlock/sprite.cpp +++ b/engines/sherlock/sprite.cpp @@ -25,101 +25,61 @@ namespace Sherlock { -/* -struct SpriteFrame { - byte *data; - int width, height; - uint16 flags; - int xofs, yofs; - byte rleMarker; -}; -*/ - Sprite::Sprite(Common::SeekableReadStream &stream) { load(stream); } Sprite::~Sprite() { + for (uint idx = 0; idx < size(); ++idx) + (*this)[idx]._frame.free(); } -int Sprite::getFrameCount() { - return _frames.size(); -} - -SpriteFrame *Sprite::getFrame(int index) { - return _frames[index]; -} - +/** + * Load the data of the sprite + */ void Sprite::load(Common::SeekableReadStream &stream) { - while (!stream.eos()) { - - debug("frameNum = %d\n", _frames.size()); - - SpriteFrame *spriteFrame = new SpriteFrame(); - - uint32 startOfs = stream.pos(); - - debug("startOfs = %08X\n", startOfs); + SpriteFrame frame; - spriteFrame->frame = NULL; - spriteFrame->width = stream.readUint16LE() + 1; - spriteFrame->height = stream.readUint16LE() + 1; - spriteFrame->flags = stream.readUint16LE(); + frame._width = stream.readUint16LE() + 1; + frame._height = stream.readUint16LE() + 1; + frame._flags = stream.readUint16LE(); stream.readUint16LE(); - debug("width = %d; height = %d; flags = %04X\n", spriteFrame->width, spriteFrame->height, spriteFrame->flags); - - if (spriteFrame->flags & 0xFF) { - spriteFrame->size = (spriteFrame->width * spriteFrame->height) / 2; - } else if (spriteFrame->flags & 0x0100) { + if (frame._flags & 0xFF) { + frame._size = (frame._width * frame._height) / 2; + } else if (frame._flags & 0x0100) { // this size includes the header size, which we subtract - spriteFrame->size = stream.readUint16LE() - 11; - spriteFrame->rleMarker = stream.readByte(); + frame._size = stream.readUint16LE() - 11; + frame._rleMarker = stream.readByte(); } else { - spriteFrame->size = spriteFrame->width * spriteFrame->height; + frame._size = frame._width * frame._height; } - spriteFrame->data = new byte[spriteFrame->size]; - stream.read(spriteFrame->data, spriteFrame->size); - - decompressFrame(spriteFrame); + // Load data for frame and decompress it + byte *data = new byte[frame._size]; + stream.read(data, frame._size); + decompressFrame(frame, data); + delete data; - /* - debug("size = %d (%08X)\n", spriteFrame->size, spriteFrame->size); - if (spriteFrame->frame) { - char fn[128]; - sndebug(fn, 128, "%04d.spr", _frames.size()); - FILE *x = fopen(fn, "wb"); - fwrite(spriteFrame->frame->pixels, spriteFrame->frame->w * spriteFrame->frame->h, 1, x); - fclose(x); - } - */ - - _frames.push_back(spriteFrame); - + push_back(frame); } - - // debug("Done: %08X\n", stream.pos()); fflush(stdout); - } -void Sprite::decompressFrame(SpriteFrame *frame) { - - frame->frame = new Graphics::Surface(); - frame->frame->create(frame->width, frame->height, Graphics::PixelFormat::createFormatCLUT8()); - - if (frame->flags & 0xFF) { - debug("Sprite::decompressFrame() 4-bits/pixel\n"); - debug("TODO\n"); - } else if (frame->flags & 0x0100) { - debug("Sprite::decompressFrame() RLE-compressed; rleMarker = %02X\n", frame->rleMarker); - const byte *src = frame->data; - byte *dst = (byte *)frame->frame->getPixels(); - for (uint16 h = 0; h < frame->height; h++) { - int16 w = frame->width; +/** + * Decompress a single frame for the sprite + */ +void Sprite::decompressFrame(SpriteFrame &frame, const byte *src) { + frame._frame.create(frame._width, frame._height, Graphics::PixelFormat::createFormatCLUT8()); + + if (frame._flags & 0xFF) { + debug("TODO: Sprite::decompressFrame() 4-bits/pixel\n"); + } else if (frame._flags & 0x0100) { + byte *dst = (byte *)frame._frame.getPixels(); + for (uint16 h = 0; h < frame._height; ++h) { + int16 w = frame._width; while (w > 0) { - if (*src == frame->rleMarker) { + if (*src == frame._rleMarker) { byte rleColor = src[1]; byte rleCount = src[2]; src += 3; @@ -133,10 +93,10 @@ void Sprite::decompressFrame(SpriteFrame *frame) { } } } else { - debug("Sprite::decompressFrame() Uncompressed\n"); - memcpy(frame->data, frame->frame->getPixels(), frame->width * frame->height); + // Uncompressed frame + Common::copy(src, src + frame._width * frame._height, + (byte *)frame._frame.getPixels()); } - } } // End of namespace Sherlock diff --git a/engines/sherlock/sprite.h b/engines/sherlock/sprite.h index f56ab588bb..1f81cf8071 100644 --- a/engines/sherlock/sprite.h +++ b/engines/sherlock/sprite.h @@ -23,32 +23,29 @@ #ifndef SHERLOCK_SPRITE_H #define SHERLOCK_SPRITE_H -#include "common/stream.h" #include "common/array.h" +#include "common/rect.h" +#include "common/stream.h" #include "graphics/surface.h" namespace Sherlock { struct SpriteFrame { - byte *data; - uint32 size; - uint16 width, height; - uint16 flags; - int xofs, yofs; - byte rleMarker; - Graphics::Surface *frame; + uint32 _size; + uint16 _width, _height; + int _flags; + Common::Point _offset; + byte _rleMarker; + Graphics::Surface _frame; }; -class Sprite { +class Sprite: public Common::Array { +private: + void load(Common::SeekableReadStream &stream); + void decompressFrame(SpriteFrame &frame, const byte *src); public: Sprite(Common::SeekableReadStream &stream); ~Sprite(); - int getFrameCount(); - SpriteFrame *getFrame(int index); -protected: - Common::Array _frames; - void load(Common::SeekableReadStream &stream); - void decompressFrame(SpriteFrame *frame); }; } // End of namespace Sherlock -- cgit v1.2.3 From 02657f5a91bba15c7d494f71d0c975ece7178861 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 16 Mar 2015 00:02:45 -0400 Subject: SHERLOCK: Fix loading of sprite for startup animation --- engines/sherlock/animation.cpp | 2 +- engines/sherlock/sprite.cpp | 47 +++++++++++++++++++++++------------------- engines/sherlock/sprite.h | 6 ++++-- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 3da0201a61..4111f6f88f 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -91,7 +91,7 @@ void Animation::playPrologue(const Common::String &filename, int minDelay, int f // Load initial image Common::String vdaName = baseName + ".vda"; Common::SeekableReadStream *vdaStream = _vm->_res->load(vdaName); - Sprite sprite(*vdaStream); + Sprite sprite(*vdaStream, true); // TODO diff --git a/engines/sherlock/sprite.cpp b/engines/sherlock/sprite.cpp index f686f0b27e..ee7c8e5019 100644 --- a/engines/sherlock/sprite.cpp +++ b/engines/sherlock/sprite.cpp @@ -25,8 +25,8 @@ namespace Sherlock { -Sprite::Sprite(Common::SeekableReadStream &stream) { - load(stream); +Sprite::Sprite(Common::SeekableReadStream &stream, bool skipPal) { + load(stream, skipPal); } Sprite::~Sprite() { @@ -37,22 +37,26 @@ Sprite::~Sprite() { /** * Load the data of the sprite */ -void Sprite::load(Common::SeekableReadStream &stream) { - while (!stream.eos()) { +void Sprite::load(Common::SeekableReadStream &stream, bool skipPal) { + while (stream.pos() < stream.size()) { SpriteFrame frame; - frame._width = stream.readUint16LE() + 1; frame._height = stream.readUint16LE() + 1; frame._flags = stream.readUint16LE(); stream.readUint16LE(); + if (skipPal) + frame._flags = 0; + if (frame._flags & 0xFF) { + // Nibble packed frame data frame._size = (frame._width * frame._height) / 2; - } else if (frame._flags & 0x0100) { + } else if (frame._flags & RLE_ENCODED) { // this size includes the header size, which we subtract frame._size = stream.readUint16LE() - 11; frame._rleMarker = stream.readByte(); } else { + // Uncompressed data frame._size = frame._width * frame._height; } @@ -74,24 +78,25 @@ void Sprite::decompressFrame(SpriteFrame &frame, const byte *src) { if (frame._flags & 0xFF) { debug("TODO: Sprite::decompressFrame() 4-bits/pixel\n"); - } else if (frame._flags & 0x0100) { + } else if (frame._flags & RLE_ENCODED) { + // RLE encoded byte *dst = (byte *)frame._frame.getPixels(); - for (uint16 h = 0; h < frame._height; ++h) { - int16 w = frame._width; - while (w > 0) { - if (*src == frame._rleMarker) { - byte rleColor = src[1]; - byte rleCount = src[2]; - src += 3; - w -= rleCount; - while (rleCount--) - *dst++ = rleColor; - } else { - *dst++ = *src++; - w--; - } + + int size = frame._width * frame._height; + while (size > 0) { + if (*src == frame._rleMarker) { + byte rleColor = src[1]; + byte rleCount = src[2]; + src += 3; + size -= rleCount; + while (rleCount--) + *dst++ = rleColor; + } else { + *dst++ = *src++; + --size; } } + assert(size == 0); } else { // Uncompressed frame Common::copy(src, src + frame._width * frame._height, diff --git a/engines/sherlock/sprite.h b/engines/sherlock/sprite.h index 1f81cf8071..17566c81bd 100644 --- a/engines/sherlock/sprite.h +++ b/engines/sherlock/sprite.h @@ -30,6 +30,8 @@ namespace Sherlock { +enum { RLE_ENCODED = 0x0100 }; + struct SpriteFrame { uint32 _size; uint16 _width, _height; @@ -41,10 +43,10 @@ struct SpriteFrame { class Sprite: public Common::Array { private: - void load(Common::SeekableReadStream &stream); + void load(Common::SeekableReadStream &stream, bool skipPal); void decompressFrame(SpriteFrame &frame, const byte *src); public: - Sprite(Common::SeekableReadStream &stream); + Sprite(Common::SeekableReadStream &stream, bool skipPal = false); ~Sprite(); }; -- cgit v1.2.3 From b762bebf27ce7c231dd17fc05bc32f72911e6ed5 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 16 Mar 2015 08:07:24 -0400 Subject: SHERLOCK: Implement sprite palette loading and fade out --- engines/sherlock/animation.cpp | 12 ++++++++++++ engines/sherlock/events.cpp | 11 ++++++++++- engines/sherlock/events.h | 4 +++- engines/sherlock/graphics.cpp | 32 ++++++++++++++++++++++++++++++++ engines/sherlock/graphics.h | 7 +++++++ engines/sherlock/sprite.cpp | 17 +++++++++++++++++ engines/sherlock/sprite.h | 3 +++ 7 files changed, 84 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 4111f6f88f..2e9eb294d3 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -67,6 +67,9 @@ Animation::Animation(SherlockEngine *vm): _vm(vm) { void Animation::playPrologue(const Common::String &filename, int minDelay, int fade, bool setPalette, int speed) { + EventsManager &events = *_vm->_events; + Screen &screen = *_vm->_screen; + // Check for any any sound frames for the given animation const int *soundFrames = checkForSoundFrames(filename); @@ -93,6 +96,15 @@ void Animation::playPrologue(const Common::String &filename, int minDelay, int f Common::SeekableReadStream *vdaStream = _vm->_res->load(vdaName); Sprite sprite(*vdaStream, true); + events.delay(minDelay); + if (fade != 0 && fade != 255) + screen.fadeToBlack(); + + if (setPalette) { + if (fade != 255) + screen.setPalette(sprite._palette); + } + // TODO diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index fdcf61e46f..4a51c4a5fb 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -115,6 +115,15 @@ void EventsManager::pollEvents() { } } +/** + * Poll for events and introduce a small delay, to allow the system to + * yield to other running programs + */ +void EventsManager::pollEventsAndWait() { + pollEvents(); + g_system->delayMillis(10); +} + /** * Check whether it's time to display the next screen frame */ @@ -149,7 +158,7 @@ void EventsManager::clearEvents() { } /** - * Delay for a given number of frames/cycles + * Delay for a given number of cycles, where each cycle is 1/60th of a second */ void EventsManager::delay(int cycles) { uint32 totalMilli = cycles * 1000 / GAME_FRAME_RATE; diff --git a/engines/sherlock/events.h b/engines/sherlock/events.h index 26f4ddb2d5..f4e6964ef5 100644 --- a/engines/sherlock/events.h +++ b/engines/sherlock/events.h @@ -31,7 +31,7 @@ namespace Sherlock { enum CursorType { CURSOR_NONE = 0 }; -#define GAME_FRAME_RATE 50 +#define GAME_FRAME_RATE 60 #define GAME_FRAME_TIME (1000 / GAME_FRAME_RATE) class SherlockEngine; @@ -63,6 +63,8 @@ public: void pollEvents(); + void pollEventsAndWait(); + Common::Point mousePos() const { return _mousePos; } uint32 getFrameCounter() const { return _frameCounter; } diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index 5c6c94606e..583389e060 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -23,6 +23,7 @@ #include "sherlock/graphics.h" #include "sherlock/sherlock.h" #include "common/system.h" +#include "graphics/palette.h" namespace Sherlock { @@ -65,4 +66,35 @@ void Screen::update() { g_system->updateScreen(); } +void Screen::getPalette(byte palette[PALETTE_SIZE]) { + g_system->getPaletteManager()->grabPalette(palette, 0, PALETTE_COUNT); +} + +void Screen::setPalette(const byte palette[PALETTE_SIZE]) { + g_system->getPaletteManager()->setPalette(palette, 0, PALETTE_COUNT); +} + +void Screen::fadeToBlack() { + const int FADE_AMOUNT = 2; + bool repeatFlag; + byte *srcP; + int count; + byte tempPalette[PALETTE_SIZE]; + + getPalette(tempPalette); + do { + repeatFlag = false; + for (srcP = &tempPalette[0], count = 0; count < PALETTE_SIZE; ++count, ++srcP) { + int v = *srcP; + if (v) { + repeatFlag = true; + *srcP = MAX(*srcP - FADE_AMOUNT, 0); + } + } + + setPalette(tempPalette); + _vm->_events->pollEventsAndWait(); + } while (repeatFlag && !_vm->shouldQuit()); +} + } // End of namespace Sherlock diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index 97daaef6e3..0385deebde 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -31,6 +31,7 @@ namespace Sherlock { #define PALETTE_SIZE 768 +#define PALETTE_COUNT 256 class SherlockEngine; @@ -53,6 +54,12 @@ public: void setFont(int fontNumber); void update(); + + void getPalette(byte palette[PALETTE_SIZE]); + + void setPalette(const byte palette[PALETTE_SIZE]); + + void fadeToBlack(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/sprite.cpp b/engines/sherlock/sprite.cpp index ee7c8e5019..c8d9ab55e3 100644 --- a/engines/sherlock/sprite.cpp +++ b/engines/sherlock/sprite.cpp @@ -21,11 +21,13 @@ */ #include "sherlock/sprite.h" +#include "sherlock/graphics.h" #include "common/debug.h" namespace Sherlock { Sprite::Sprite(Common::SeekableReadStream &stream, bool skipPal) { + Common::fill(&_palette[0], &_palette[PALETTE_SIZE], 0); load(stream, skipPal); } @@ -38,6 +40,8 @@ Sprite::~Sprite() { * Load the data of the sprite */ void Sprite::load(Common::SeekableReadStream &stream, bool skipPal) { + loadPalette(stream); + while (stream.pos() < stream.size()) { SpriteFrame frame; frame._width = stream.readUint16LE() + 1; @@ -70,6 +74,19 @@ void Sprite::load(Common::SeekableReadStream &stream, bool skipPal) { } } +/** + * Gets the palette at the start of the sprite file + */ +void Sprite::loadPalette(Common::SeekableReadStream &stream) { + int v1 = stream.readUint16LE() + 1; + int v2 = stream.readUint16LE() + 1; + int size = v1 * v2; + assert((size - 12) == PALETTE_SIZE); + + stream.seek(4 + 12, SEEK_CUR); + stream.read(&_palette[0], PALETTE_SIZE); +} + /** * Decompress a single frame for the sprite */ diff --git a/engines/sherlock/sprite.h b/engines/sherlock/sprite.h index 17566c81bd..5a510b2548 100644 --- a/engines/sherlock/sprite.h +++ b/engines/sherlock/sprite.h @@ -44,7 +44,10 @@ struct SpriteFrame { class Sprite: public Common::Array { private: void load(Common::SeekableReadStream &stream, bool skipPal); + void loadPalette(Common::SeekableReadStream &stream); void decompressFrame(SpriteFrame &frame, const byte *src); +public: + byte _palette[256 * 3]; public: Sprite(Common::SeekableReadStream &stream, bool skipPal = false); ~Sprite(); -- cgit v1.2.3 From 0ee3f1895f6b6dcf4bbb70ba309fb66d0ca39613 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 16 Mar 2015 22:42:19 -0400 Subject: SHERLOCK: Beginnings of animation sequence loop --- engines/sherlock/animation.cpp | 69 +++++++++++++++++++++++++++++++++--- engines/sherlock/animation.h | 2 +- engines/sherlock/graphics.cpp | 26 ++++++++++++++ engines/sherlock/graphics.h | 2 ++ engines/sherlock/scalpel/scalpel.cpp | 34 +++++++++--------- engines/sherlock/scalpel/scalpel.h | 8 ++--- engines/sherlock/sherlock.cpp | 1 + engines/sherlock/sound.cpp | 10 +++++- engines/sherlock/sound.h | 12 ++++++- engines/sherlock/sprite.cpp | 13 +++---- engines/sherlock/sprite.h | 5 ++- 11 files changed, 145 insertions(+), 37 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 2e9eb294d3..e4ec06b741 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -65,10 +65,13 @@ static const int NO_FRAMES = FRAMES_END; Animation::Animation(SherlockEngine *vm): _vm(vm) { } -void Animation::playPrologue(const Common::String &filename, int minDelay, int fade, +bool Animation::playPrologue(const Common::String &filename, int minDelay, int fade, bool setPalette, int speed) { EventsManager &events = *_vm->_events; Screen &screen = *_vm->_screen; + Sound &sound = *_vm->_sound; + int soundNumber = 0; + sound._playingEpilogue = true; // Check for any any sound frames for the given animation const int *soundFrames = checkForSoundFrames(filename); @@ -89,7 +92,6 @@ void Animation::playPrologue(const Common::String &filename, int minDelay, int f stream = _vm->_res->load(vdxName, "epilog2.lib"); else stream = _vm->_res->load(vdxName, "epilogoue.lib"); - int resourceIndex = _vm->_res->resourceIndex(); // Load initial image Common::String vdaName = baseName + ".vda"; @@ -99,16 +101,75 @@ void Animation::playPrologue(const Common::String &filename, int minDelay, int f events.delay(minDelay); if (fade != 0 && fade != 255) screen.fadeToBlack(); - + fade = 0; //***DEBUG**** if (setPalette) { if (fade != 255) screen.setPalette(sprite._palette); } - // TODO + int frameNumber = 0; + int spriteFrame; + Common::Point pt; + bool skipped = false; + while (!_vm->shouldQuit()) { + spriteFrame = stream->readSint16LE(); + if (spriteFrame != -1) { + if (spriteFrame < 0) { + spriteFrame = ABS(spriteFrame); + pt.x = stream->readUint16LE(); + pt.y = stream->readUint16LE(); + } else { + pt = sprite[spriteFrame]._position; + } + + screen.copyFrom(sprite[spriteFrame]._frame); + events.pollEventsAndWait(); + } else { + if (fade == 255) { + // Gradual fade in + if (screen.equalizePalette(sprite._palette) == 0) + fade = 0; + } + + // Check if we've reached a frame with sound + if (frameNumber++ == *soundFrames) { + ++soundNumber; + ++soundFrames; + Common::String fname = _vm->_soundOverride.empty() ? + Common::String::format("%s%01d", baseName.c_str(), soundNumber) : + Common::String::format("%s%02d", baseName.c_str(), soundNumber); + + if (sound._voicesEnabled) + sound.playSound(fname); + } + + events.delay(speed); + if (stream->readSint16LE() == -2) + // End of animation + break; + stream->seek(-2, SEEK_CUR); + } + if (events.isKeyPressed()) { + Common::KeyState keyState = events.getKey(); + if (keyState.keycode == Common::KEYCODE_ESCAPE || + keyState.keycode == Common::KEYCODE_SPACE) { + skipped = true; + break; + } + } else if (events._mouseClicked) { + skipped = true; + break; + } + } + + events.clearEvents(); + sound.stopSound(); delete stream; + sound._playingEpilogue = false; + + return !skipped && !_vm->shouldQuit(); } /** diff --git a/engines/sherlock/animation.h b/engines/sherlock/animation.h index 14384cfa28..da4c5baad7 100644 --- a/engines/sherlock/animation.h +++ b/engines/sherlock/animation.h @@ -39,7 +39,7 @@ public: public: Animation(SherlockEngine *vm); - void playPrologue(const Common::String &filename, int minDelay, int fade, bool setPalette, int speed); + bool playPrologue(const Common::String &filename, int minDelay, int fade, bool setPalette, int speed); }; } // End of namespace Sherlock diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index 583389e060..f4fe6b6b46 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -63,6 +63,7 @@ void Screen::setFont(int fontNumber) { } void Screen::update() { + g_system->copyRectToScreen(getPixels(), this->w, 0, 0, this->w, this->h); g_system->updateScreen(); } @@ -74,6 +75,31 @@ void Screen::setPalette(const byte palette[PALETTE_SIZE]) { g_system->getPaletteManager()->setPalette(palette, 0, PALETTE_COUNT); } +int Screen::equalizePalette(const byte palette[PALETTE_SIZE]) { + int total = 0; + byte tempPalette[PALETTE_SIZE]; + getPalette(tempPalette); + + // For any palette component that doesn't already match the given destination + // palette, change by 1 towards the reference palette component + for (int idx = 0; idx < PALETTE_SIZE; ++idx) { + if (tempPalette[idx] > palette[idx]) + { + --tempPalette[idx]; + ++total; + } else if (tempPalette[idx] < palette[idx]) { + ++tempPalette[idx]; + ++total; + } + } + + if (total > 0) + // Palette changed, so reload it + setPalette(tempPalette); + + return total; +} + void Screen::fadeToBlack() { const int FADE_AMOUNT = 2; bool repeatFlag; diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index 0385deebde..c6611db1ce 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -59,6 +59,8 @@ public: void setPalette(const byte palette[PALETTE_SIZE]); + int equalizePalette(const byte palette[PALETTE_SIZE]); + void fadeToBlack(); }; diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 0b651bbb69..90a93de1b1 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -45,21 +45,21 @@ void ScalpelEngine::initialize() { * Show the opening sequence */ void ScalpelEngine::showOpening() { - if (!_events->isKeyPressed()) - showCityCutscene(); - if (!_events->isKeyPressed()) - showAlleyCutscene(); - if (!_events->isKeyPressed()) - showStreetCutscene(); - if (!_events->isKeyPressed()) - showOfficeCutscene(); + if (!showCityCutscene()) + return; + if (!showAlleyCutscene()) + return; + if (!showStreetCutscene()) + return; + if (!showOfficeCutscene()) + return; _events->clearEvents(); _sound->stopMusic(); } -void ScalpelEngine::showCityCutscene() { - byte palette[PALETTE_SIZE]; +bool ScalpelEngine::showCityCutscene() { +// byte palette[PALETTE_SIZE]; _sound->playMusic("prolog1.mus"); _titleOverride = "title.lib"; @@ -67,21 +67,21 @@ void ScalpelEngine::showCityCutscene() { _animation->playPrologue("26open1", 1, 255, true, 2); // TODO + return true; } -void ScalpelEngine::showAlleyCutscene() { - +bool ScalpelEngine::showAlleyCutscene() { + return true; } -void ScalpelEngine::showStreetCutscene() { - +bool ScalpelEngine::showStreetCutscene() { + return true; } -void ScalpelEngine::showOfficeCutscene() { - +bool ScalpelEngine::showOfficeCutscene() { + return true; } - } // End of namespace Scalpel } // End of namespace Scalpel diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h index 5da33e1d52..584bd78a20 100644 --- a/engines/sherlock/scalpel/scalpel.h +++ b/engines/sherlock/scalpel/scalpel.h @@ -31,10 +31,10 @@ namespace Scalpel { class ScalpelEngine : public SherlockEngine { private: - void showCityCutscene(); - void showAlleyCutscene(); - void showStreetCutscene(); - void showOfficeCutscene(); + bool showCityCutscene(); + bool showAlleyCutscene(); + bool showStreetCutscene(); + bool showOfficeCutscene(); protected: virtual void initialize(); diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index cb0472feff..1fba746f8d 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -80,6 +80,7 @@ void SherlockEngine::initialize() { _res = new Resources(); _rooms = new Rooms(); _screen = new Screen(this); + _sound = new Sound(this); _talk = new Talk(); } diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index f16dd5a80d..0957315a35 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -25,9 +25,13 @@ namespace Sherlock { Sound::Sound(SherlockEngine *vm): _vm(vm) { + _sfxEnabled = true; + _musicEnabled = true; + _voicesEnabled = true; + _playingEpilogue = false; } -void Sound::playSound(const Common::String &name) { +void Sound::playSound(const Common::String &name, WaitType waitType) { // TODO } @@ -43,6 +47,10 @@ void Sound::clearCache() { // TODO } +void Sound::stopSound() { + // TODO +} + void Sound::playMusic(const Common::String &name) { // TODO } diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index b1759a9c8e..7775016c94 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -30,16 +30,26 @@ namespace Sherlock { class SherlockEngine; +enum WaitType { + WAIT_RETURN_IMMEDIATELY = 0, WAIT_FINISH = 1, WAIT_KBD_OR_FINISH = 2 +}; + class Sound { private: SherlockEngine *_vm; +public: + bool _sfxEnabled; + bool _musicEnabled; + bool _voicesEnabled; + bool _playingEpilogue; public: Sound(SherlockEngine *vm); - void playSound(const Common::String &name); + void playSound(const Common::String &name, WaitType waitType = WAIT_RETURN_IMMEDIATELY); void cacheSound(const Common::String &name, int index); void playCachedSound(int index); void clearCache(); + void stopSound(); void playMusic(const Common::String &name); void stopMusic(); diff --git a/engines/sherlock/sprite.cpp b/engines/sherlock/sprite.cpp index c8d9ab55e3..9883d078ae 100644 --- a/engines/sherlock/sprite.cpp +++ b/engines/sherlock/sprite.cpp @@ -46,16 +46,16 @@ void Sprite::load(Common::SeekableReadStream &stream, bool skipPal) { SpriteFrame frame; frame._width = stream.readUint16LE() + 1; frame._height = stream.readUint16LE() + 1; - frame._flags = stream.readUint16LE(); - stream.readUint16LE(); + frame._flags = stream.readByte(); + frame._position.x = stream.readUint16LE(); + frame._position.y = stream.readByte(); - if (skipPal) - frame._flags = 0; + frame._rleEncoded = !skipPal && (frame._position.x == 1); if (frame._flags & 0xFF) { // Nibble packed frame data frame._size = (frame._width * frame._height) / 2; - } else if (frame._flags & RLE_ENCODED) { + } else if (frame._rleEncoded) { // this size includes the header size, which we subtract frame._size = stream.readUint16LE() - 11; frame._rleMarker = stream.readByte(); @@ -78,6 +78,7 @@ void Sprite::load(Common::SeekableReadStream &stream, bool skipPal) { * Gets the palette at the start of the sprite file */ void Sprite::loadPalette(Common::SeekableReadStream &stream) { + // Read in the palette int v1 = stream.readUint16LE() + 1; int v2 = stream.readUint16LE() + 1; int size = v1 * v2; @@ -95,7 +96,7 @@ void Sprite::decompressFrame(SpriteFrame &frame, const byte *src) { if (frame._flags & 0xFF) { debug("TODO: Sprite::decompressFrame() 4-bits/pixel\n"); - } else if (frame._flags & RLE_ENCODED) { + } else if (frame._rleEncoded) { // RLE encoded byte *dst = (byte *)frame._frame.getPixels(); diff --git a/engines/sherlock/sprite.h b/engines/sherlock/sprite.h index 5a510b2548..8aedbdb9c5 100644 --- a/engines/sherlock/sprite.h +++ b/engines/sherlock/sprite.h @@ -30,13 +30,12 @@ namespace Sherlock { -enum { RLE_ENCODED = 0x0100 }; - struct SpriteFrame { uint32 _size; uint16 _width, _height; int _flags; - Common::Point _offset; + bool _rleEncoded; + Common::Point _position; byte _rleMarker; Graphics::Surface _frame; }; -- cgit v1.2.3 From cb874522e4fac3108070d5054977696a58ddb510 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 16 Mar 2015 23:38:58 -0400 Subject: SHERLOCK: Implement screen clipping for sprite drawing --- engines/sherlock/animation.cpp | 22 ++++++++++++---------- engines/sherlock/graphics.cpp | 38 ++++++++++++++++++++++++++++++++++++++ engines/sherlock/graphics.h | 6 ++++++ 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index e4ec06b741..581971820d 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -101,7 +101,7 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f events.delay(minDelay); if (fade != 0 && fade != 255) screen.fadeToBlack(); - fade = 0; //***DEBUG**** + if (setPalette) { if (fade != 255) screen.setPalette(sprite._palette); @@ -112,19 +112,26 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f Common::Point pt; bool skipped = false; while (!_vm->shouldQuit()) { + // Get the next sprite to display spriteFrame = stream->readSint16LE(); - if (spriteFrame != -1) { + + if (spriteFrame == -2) { + // End of animation reached + break; + } else if (spriteFrame != -1) { + // Read position from either animation stream or the sprite frame itself if (spriteFrame < 0) { - spriteFrame = ABS(spriteFrame); + spriteFrame += 32769; pt.x = stream->readUint16LE(); pt.y = stream->readUint16LE(); } else { pt = sprite[spriteFrame]._position; } - screen.copyFrom(sprite[spriteFrame]._frame); - events.pollEventsAndWait(); + // Draw the sprite + screen.copyFrom(sprite[spriteFrame]._frame, pt); } else { + // No sprite to show for this animation frame if (fade == 255) { // Gradual fade in if (screen.equalizePalette(sprite._palette) == 0) @@ -144,11 +151,6 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f } events.delay(speed); - - if (stream->readSint16LE() == -2) - // End of animation - break; - stream->seek(-2, SEEK_CUR); } if (events.isKeyPressed()) { diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index f4fe6b6b46..fbfd3b7b45 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -35,6 +35,44 @@ Surface::~Surface() { free(); } +/** + * Draws a surface into another + */ +void Surface::copyFrom(const Graphics::Surface &src) { + copyFrom(src, Common::Point()); +} + +/** + * Draws a surface at a given position within this surface + */ +void Surface::copyFrom(const Graphics::Surface &src, const Common::Point &pt) { + Common::Rect drawRect(0, 0, src.w, src.h); + Common::Point destPt = pt; + + if (destPt.x < 0) { + drawRect.left += -destPt.x; + destPt.x = 0; + } + if (destPt.y < 0) { + drawRect.top += -destPt.y; + destPt.y = 0; + } + int right = destPt.x + src.w; + if (right > this->w) { + drawRect.right -= (right - this->w); + } + int bottom = destPt.y + src.h; + if (bottom > this->h) { + drawRect.bottom -= (bottom - this->h); + } + + if (drawRect.isValidRect()) { + addDirtyRect(Common::Rect(destPt.x, destPt.y, destPt.x + drawRect.width(), + destPt.y + drawRect.height())); + copyRectToSurface(src, destPt.x, destPt.y, drawRect); + } +} + void Surface::fillRect(int x1, int y1, int x2, int y2, byte color) { Graphics::Surface::fillRect(Common::Rect(x1, y1, x2, y2), color); } diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index c6611db1ce..79cffa839a 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -36,9 +36,15 @@ namespace Sherlock { class SherlockEngine; class Surface : public Graphics::Surface { +protected: + virtual void addDirtyRect(const Common::Rect &r) {} public: Surface(uint16 width, uint16 height); ~Surface(); + + void copyFrom(const Graphics::Surface &src); + void copyFrom(const Graphics::Surface &src, const Common::Point &pt); + void fillRect(int x1, int y1, int x2, int y2, byte color); void drawSprite(int x, int y, SpriteFrame *spriteFrame, bool flipped = false, bool altFlag = false); }; -- cgit v1.2.3 From 4b5cbc58976c1ed2a58c496aeb5f327352fc38a6 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 16 Mar 2015 23:52:08 -0400 Subject: SHERLOCK: Split Screen class into it's own file --- engines/sherlock/graphics.cpp | 84 --------------------------------- engines/sherlock/graphics.h | 29 ------------ engines/sherlock/module.mk | 1 + engines/sherlock/screen.cpp | 107 ++++++++++++++++++++++++++++++++++++++++++ engines/sherlock/screen.h | 61 ++++++++++++++++++++++++ engines/sherlock/sherlock.h | 2 +- engines/sherlock/sprite.cpp | 2 +- 7 files changed, 171 insertions(+), 115 deletions(-) create mode 100644 engines/sherlock/screen.cpp create mode 100644 engines/sherlock/screen.h diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index fbfd3b7b45..23d3b443e8 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -77,88 +77,4 @@ void Surface::fillRect(int x1, int y1, int x2, int y2, byte color) { Graphics::Surface::fillRect(Common::Rect(x1, y1, x2, y2), color); } -void Surface::drawSprite(int x, int y, SpriteFrame *spriteFrame, bool flipped, bool altFlag) { - - -} - -/*----------------------------------------------------------------*/ - -Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), _vm(vm), - _backBuffer1(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), - _backBuffer2(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT) { - setFont(1); -} - -void Screen::setFont(int fontNumber) { - _fontNumber = fontNumber; - Common::String fname = Common::String::format("FONT%d.VGS", fontNumber); - Common::SeekableReadStream *stream = _vm->_res->load(fname); - - debug("TODO: Loading font %s, size - %d", fname.c_str(), stream->size()); - - delete stream; -} - -void Screen::update() { - g_system->copyRectToScreen(getPixels(), this->w, 0, 0, this->w, this->h); - g_system->updateScreen(); -} - -void Screen::getPalette(byte palette[PALETTE_SIZE]) { - g_system->getPaletteManager()->grabPalette(palette, 0, PALETTE_COUNT); -} - -void Screen::setPalette(const byte palette[PALETTE_SIZE]) { - g_system->getPaletteManager()->setPalette(palette, 0, PALETTE_COUNT); -} - -int Screen::equalizePalette(const byte palette[PALETTE_SIZE]) { - int total = 0; - byte tempPalette[PALETTE_SIZE]; - getPalette(tempPalette); - - // For any palette component that doesn't already match the given destination - // palette, change by 1 towards the reference palette component - for (int idx = 0; idx < PALETTE_SIZE; ++idx) { - if (tempPalette[idx] > palette[idx]) - { - --tempPalette[idx]; - ++total; - } else if (tempPalette[idx] < palette[idx]) { - ++tempPalette[idx]; - ++total; - } - } - - if (total > 0) - // Palette changed, so reload it - setPalette(tempPalette); - - return total; -} - -void Screen::fadeToBlack() { - const int FADE_AMOUNT = 2; - bool repeatFlag; - byte *srcP; - int count; - byte tempPalette[PALETTE_SIZE]; - - getPalette(tempPalette); - do { - repeatFlag = false; - for (srcP = &tempPalette[0], count = 0; count < PALETTE_SIZE; ++count, ++srcP) { - int v = *srcP; - if (v) { - repeatFlag = true; - *srcP = MAX(*srcP - FADE_AMOUNT, 0); - } - } - - setPalette(tempPalette); - _vm->_events->pollEventsAndWait(); - } while (repeatFlag && !_vm->shouldQuit()); -} - } // End of namespace Sherlock diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index 79cffa839a..1765cf04ae 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -26,15 +26,8 @@ #include "common/rect.h" #include "graphics/surface.h" -#include "sherlock/sprite.h" - namespace Sherlock { -#define PALETTE_SIZE 768 -#define PALETTE_COUNT 256 - -class SherlockEngine; - class Surface : public Graphics::Surface { protected: virtual void addDirtyRect(const Common::Rect &r) {} @@ -46,28 +39,6 @@ public: void copyFrom(const Graphics::Surface &src, const Common::Point &pt); void fillRect(int x1, int y1, int x2, int y2, byte color); - void drawSprite(int x, int y, SpriteFrame *spriteFrame, bool flipped = false, bool altFlag = false); -}; - -class Screen : public Surface { -private: - SherlockEngine *_vm; - int _fontNumber; - Surface _backBuffer1, _backBuffer2; -public: - Screen(SherlockEngine *vm); - - void setFont(int fontNumber); - - void update(); - - void getPalette(byte palette[PALETTE_SIZE]); - - void setPalette(const byte palette[PALETTE_SIZE]); - - int equalizePalette(const byte palette[PALETTE_SIZE]); - - void fadeToBlack(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk index 7009f49d3f..06186f1504 100644 --- a/engines/sherlock/module.mk +++ b/engines/sherlock/module.mk @@ -12,6 +12,7 @@ MODULE_OBJS = \ journal.o \ resources.o \ room.o \ + screen.o \ sherlock.o \ sound.o \ sprite.o \ diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp new file mode 100644 index 0000000000..d3fe68e367 --- /dev/null +++ b/engines/sherlock/screen.cpp @@ -0,0 +1,107 @@ +/* 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 "sherlock/screen.h" +#include "sherlock/sherlock.h" +#include "common/system.h" +#include "graphics/palette.h" + +namespace Sherlock { + +Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), _vm(vm), + _backBuffer1(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), + _backBuffer2(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT) { + setFont(1); +} + +void Screen::setFont(int fontNumber) { + _fontNumber = fontNumber; + Common::String fname = Common::String::format("FONT%d.VGS", fontNumber); + Common::SeekableReadStream *stream = _vm->_res->load(fname); + + debug("TODO: Loading font %s, size - %d", fname.c_str(), stream->size()); + + delete stream; +} + +void Screen::update() { + g_system->copyRectToScreen(getPixels(), this->w, 0, 0, this->w, this->h); + g_system->updateScreen(); +} + +void Screen::getPalette(byte palette[PALETTE_SIZE]) { + g_system->getPaletteManager()->grabPalette(palette, 0, PALETTE_COUNT); +} + +void Screen::setPalette(const byte palette[PALETTE_SIZE]) { + g_system->getPaletteManager()->setPalette(palette, 0, PALETTE_COUNT); +} + +int Screen::equalizePalette(const byte palette[PALETTE_SIZE]) { + int total = 0; + byte tempPalette[PALETTE_SIZE]; + getPalette(tempPalette); + + // For any palette component that doesn't already match the given destination + // palette, change by 1 towards the reference palette component + for (int idx = 0; idx < PALETTE_SIZE; ++idx) { + if (tempPalette[idx] > palette[idx]) + { + --tempPalette[idx]; + ++total; + } else if (tempPalette[idx] < palette[idx]) { + ++tempPalette[idx]; + ++total; + } + } + + if (total > 0) + // Palette changed, so reload it + setPalette(tempPalette); + + return total; +} + +void Screen::fadeToBlack() { + const int FADE_AMOUNT = 2; + bool repeatFlag; + byte *srcP; + int count; + byte tempPalette[PALETTE_SIZE]; + + getPalette(tempPalette); + do { + repeatFlag = false; + for (srcP = &tempPalette[0], count = 0; count < PALETTE_SIZE; ++count, ++srcP) { + int v = *srcP; + if (v) { + repeatFlag = true; + *srcP = MAX(*srcP - FADE_AMOUNT, 0); + } + } + + setPalette(tempPalette); + _vm->_events->pollEventsAndWait(); + } while (repeatFlag && !_vm->shouldQuit()); +} + +} // End of namespace Sherlock diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h new file mode 100644 index 0000000000..3d1ad785e6 --- /dev/null +++ b/engines/sherlock/screen.h @@ -0,0 +1,61 @@ +/* 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 SHERLOCK_SCREEN_H +#define SHERLOCK_SCREEN_H + +#include "common/rect.h" +#include "graphics/surface.h" + +#include "sherlock/graphics.h" + +namespace Sherlock { + +#define PALETTE_SIZE 768 +#define PALETTE_COUNT 256 + +class SherlockEngine; + +class Screen : public Surface { +private: + SherlockEngine *_vm; + int _fontNumber; + Surface _backBuffer1, _backBuffer2; +public: + Screen(SherlockEngine *vm); + + void setFont(int fontNumber); + + void update(); + + void getPalette(byte palette[PALETTE_SIZE]); + + void setPalette(const byte palette[PALETTE_SIZE]); + + int equalizePalette(const byte palette[PALETTE_SIZE]); + + void fadeToBlack(); +}; + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index b04a14e8ac..8d24a78c81 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -33,10 +33,10 @@ #include "sherlock/animation.h" #include "sherlock/debugger.h" #include "sherlock/events.h" -#include "sherlock/graphics.h" #include "sherlock/journal.h" #include "sherlock/resources.h" #include "sherlock/room.h" +#include "sherlock/screen.h" #include "sherlock/sound.h" #include "sherlock/talk.h" diff --git a/engines/sherlock/sprite.cpp b/engines/sherlock/sprite.cpp index 9883d078ae..ca70932155 100644 --- a/engines/sherlock/sprite.cpp +++ b/engines/sherlock/sprite.cpp @@ -21,7 +21,7 @@ */ #include "sherlock/sprite.h" -#include "sherlock/graphics.h" +#include "sherlock/screen.h" #include "common/debug.h" namespace Sherlock { -- cgit v1.2.3 From 59c124aa609bc872ac00175729728bdd825e6f1d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 17 Mar 2015 00:01:12 -0400 Subject: SHERLOCK: Add dirty rect handling --- engines/sherlock/screen.cpp | 68 ++++++++++++++++++++++++++++++++++++++++++++- engines/sherlock/screen.h | 8 ++++++ 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index d3fe68e367..6dcb37c448 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -44,8 +44,21 @@ void Screen::setFont(int fontNumber) { } void Screen::update() { - g_system->copyRectToScreen(getPixels(), this->w, 0, 0, this->w, this->h); + // Merge the dirty rects + mergeDirtyRects(); + + // Loop through copying dirty areas to the physical screen + Common::List::iterator i; + for (i = _dirtyRects.begin(); i != _dirtyRects.end(); ++i) { + const Common::Rect &r = *i; + const byte *srcP = (const byte *)getBasePtr(r.left, r.top); + g_system->copyRectToScreen(srcP, this->pitch, r.left, r.top, + r.width(), r.height()); + } + + // Signal the physical screen to update g_system->updateScreen(); + _dirtyRects.clear(); } void Screen::getPalette(byte palette[PALETTE_SIZE]) { @@ -104,4 +117,57 @@ void Screen::fadeToBlack() { } while (repeatFlag && !_vm->shouldQuit()); } +/** + * Adds a rectangle to the list of modified areas of the screen during the + * current frame + */ +void Screen::addDirtyRect(const Common::Rect &r) { + _dirtyRects.push_back(r); + assert(r.isValidRect() && r.width() > 0 && r.height() > 0); +} + +/** + * Merges together overlapping dirty areas of the screen + */ +void Screen::mergeDirtyRects() { + Common::List::iterator rOuter, rInner; + + // Ensure dirty rect list has at least two entries + rOuter = _dirtyRects.begin(); + for (int i = 0; i < 2; ++i, ++rOuter) { + if (rOuter == _dirtyRects.end()) + return; + } + + // Process the dirty rect list to find any rects to merge + for (rOuter = _dirtyRects.begin(); rOuter != _dirtyRects.end(); ++rOuter) { + rInner = rOuter; + while (++rInner != _dirtyRects.end()) { + + if ((*rOuter).intersects(*rInner)) { + // these two rectangles overlap or + // are next to each other - merge them + + unionRectangle(*rOuter, *rOuter, *rInner); + + // remove the inner rect from the list + _dirtyRects.erase(rInner); + + // move back to beginning of list + rInner = rOuter; + } + } + } +} + +/** + * Returns the union of two dirty area rectangles + */ +bool Screen::unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2) { + destRect = src1; + destRect.extend(src2); + + return !destRect.isEmpty(); +} + } // End of namespace Sherlock diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 3d1ad785e6..62d3944d04 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -23,6 +23,7 @@ #ifndef SHERLOCK_SCREEN_H #define SHERLOCK_SCREEN_H +#include "common/list.h" #include "common/rect.h" #include "graphics/surface.h" @@ -40,6 +41,13 @@ private: SherlockEngine *_vm; int _fontNumber; Surface _backBuffer1, _backBuffer2; + Common::List _dirtyRects; + + void mergeDirtyRects(); + + bool unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2); +protected: + virtual void addDirtyRect(const Common::Rect &r); public: Screen(SherlockEngine *vm); -- cgit v1.2.3 From 51989953b616c97db4d3d433fffee2ab8395606b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 17 Mar 2015 08:12:19 -0400 Subject: SHERLOCK: Implement transparent sprite drawing --- engines/sherlock/animation.cpp | 2 +- engines/sherlock/graphics.cpp | 54 +++++++++++++++++++++++++++++++++++------- engines/sherlock/graphics.h | 4 ++-- 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 581971820d..0e932b6dd2 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -129,7 +129,7 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f } // Draw the sprite - screen.copyFrom(sprite[spriteFrame]._frame, pt); + screen.transBlitFrom(sprite[spriteFrame]._frame, pt); } else { // No sprite to show for this animation frame if (fade == 255) { diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index 23d3b443e8..2bce822707 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -35,17 +35,10 @@ Surface::~Surface() { free(); } -/** - * Draws a surface into another - */ -void Surface::copyFrom(const Graphics::Surface &src) { - copyFrom(src, Common::Point()); -} - /** * Draws a surface at a given position within this surface */ -void Surface::copyFrom(const Graphics::Surface &src, const Common::Point &pt) { +void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt) { Common::Rect drawRect(0, 0, src.w, src.h); Common::Point destPt = pt; @@ -73,6 +66,51 @@ void Surface::copyFrom(const Graphics::Surface &src, const Common::Point &pt) { } } + +/** +* Draws a surface at a given position within this surface with transparency +*/ +void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &pt) { + Common::Rect drawRect(0, 0, src.w, src.h); + Common::Point destPt = pt; + + if (destPt.x < 0) { + drawRect.left += -destPt.x; + destPt.x = 0; + } + if (destPt.y < 0) { + drawRect.top += -destPt.y; + destPt.y = 0; + } + int right = destPt.x + src.w; + if (right > this->w) { + drawRect.right -= (right - this->w); + } + int bottom = destPt.y + src.h; + if (bottom > this->h) { + drawRect.bottom -= (bottom - this->h); + } + + if (!drawRect.isValidRect()) + return; + + addDirtyRect(Common::Rect(destPt.x, destPt.y, destPt.x + drawRect.width(), + destPt.y + drawRect.height())); + + // Draw loop + const int TRANSPARENCY = 0xFF; + for (int yp = 0; yp < drawRect.height(); ++yp) { + const byte *srcP = (const byte *)src.getBasePtr(drawRect.left, drawRect.top + yp); + byte *destP = (byte *)getBasePtr(destPt.x, destPt.y + yp); + + for (int xp = 0; xp < drawRect.width(); ++xp, ++srcP, ++destP) { + if (*srcP != TRANSPARENCY) + *destP = *srcP; + } + } +} + + void Surface::fillRect(int x1, int y1, int x2, int y2, byte color) { Graphics::Surface::fillRect(Common::Rect(x1, y1, x2, y2), color); } diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index 1765cf04ae..983a22a790 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -35,8 +35,8 @@ public: Surface(uint16 width, uint16 height); ~Surface(); - void copyFrom(const Graphics::Surface &src); - void copyFrom(const Graphics::Surface &src, const Common::Point &pt); + void blitFrom(const Graphics::Surface &src, const Common::Point &pt); + void transBlitFrom(const Graphics::Surface &src, const Common::Point &pt); void fillRect(int x1, int y1, int x2, int y2, byte color); }; -- cgit v1.2.3 From ec4319923452bebade836b43a912de06958315a6 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 17 Mar 2015 08:31:29 -0400 Subject: SHERLOCK: Convert 6-bit palettes to 8-bit VGA palettes --- engines/sherlock/screen.cpp | 4 ++-- engines/sherlock/screen.h | 1 + engines/sherlock/sprite.cpp | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 6dcb37c448..500abc1197 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -79,10 +79,10 @@ int Screen::equalizePalette(const byte palette[PALETTE_SIZE]) { for (int idx = 0; idx < PALETTE_SIZE; ++idx) { if (tempPalette[idx] > palette[idx]) { - --tempPalette[idx]; + tempPalette[idx] = MAX((int)palette[idx], (int)tempPalette[idx] - 4); ++total; } else if (tempPalette[idx] < palette[idx]) { - ++tempPalette[idx]; + tempPalette[idx] = MIN((int)palette[idx], (int)tempPalette[idx] + 4); ++total; } } diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 62d3944d04..d244452771 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -33,6 +33,7 @@ namespace Sherlock { #define PALETTE_SIZE 768 #define PALETTE_COUNT 256 +#define VGA_COLOR_TRANS(x) ((x) * 255 / 63) class SherlockEngine; diff --git a/engines/sherlock/sprite.cpp b/engines/sherlock/sprite.cpp index ca70932155..be5a0e0d27 100644 --- a/engines/sherlock/sprite.cpp +++ b/engines/sherlock/sprite.cpp @@ -85,7 +85,8 @@ void Sprite::loadPalette(Common::SeekableReadStream &stream) { assert((size - 12) == PALETTE_SIZE); stream.seek(4 + 12, SEEK_CUR); - stream.read(&_palette[0], PALETTE_SIZE); + for (int idx = 0; idx < PALETTE_SIZE; ++idx) + _palette[idx] = VGA_COLOR_TRANS(stream.readByte()); } /** -- cgit v1.2.3 From 62f3f5d14e391cdac0bbfe200cdde2e4773afba4 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 17 Mar 2015 23:09:04 -0400 Subject: SHERLOCK: Remainder of showCityCutscene implemented --- engines/sherlock/animation.cpp | 7 ++- engines/sherlock/events.cpp | 23 +++++++--- engines/sherlock/events.h | 4 +- engines/sherlock/graphics.cpp | 39 ++++++++++++---- engines/sherlock/graphics.h | 6 ++- engines/sherlock/scalpel/scalpel.cpp | 70 ++++++++++++++++++++++++++--- engines/sherlock/screen.cpp | 87 ++++++++++++++++++++++++++++-------- engines/sherlock/screen.h | 11 ++++- engines/sherlock/sherlock.cpp | 3 +- engines/sherlock/sherlock.h | 8 +++- engines/sherlock/sprite.cpp | 37 +++++++++++---- engines/sherlock/sprite.h | 12 ++++- 12 files changed, 246 insertions(+), 61 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 0e932b6dd2..6788cc51d7 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -95,10 +95,9 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f // Load initial image Common::String vdaName = baseName + ".vda"; - Common::SeekableReadStream *vdaStream = _vm->_res->load(vdaName); - Sprite sprite(*vdaStream, true); + Sprite sprite(vdaName, true); - events.delay(minDelay); + events.wait(minDelay); if (fade != 0 && fade != 255) screen.fadeToBlack(); @@ -150,7 +149,7 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f sound.playSound(fname); } - events.delay(speed); + events.wait(speed); } if (events.isKeyPressed()) { diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index 4a51c4a5fb..c6c013193c 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -158,17 +158,26 @@ void EventsManager::clearEvents() { } /** - * Delay for a given number of cycles, where each cycle is 1/60th of a second + * Delay for a given number of game frames, where each frame is 1/60th of a second */ -void EventsManager::delay(int cycles) { - uint32 totalMilli = cycles * 1000 / GAME_FRAME_RATE; - uint32 delayEnd = g_system->getMillis() + totalMilli; +void EventsManager::wait(int numFrames) { + uint32 totalMilli = numFrames * 1000 / GAME_FRAME_RATE; + delay(totalMilli); +} + +bool EventsManager::delay(uint32 time, bool interruptable) { + uint32 delayEnd = g_system->getMillis() + time; while (!_vm->shouldQuit() && g_system->getMillis() < delayEnd) { - g_system->delayMillis(10); + pollEventsAndWait(); - pollEvents(); + if (interruptable && (isKeyPressed() || _mouseClicked)) { + clearEvents(); + return false; + } } + + return true; } /** @@ -183,7 +192,7 @@ void EventsManager::waitForNextFrame() { uint32 frameCtr = getFrameCounter(); while (!_vm->shouldQuit() && frameCtr == _frameCounter) { - delay(1); + pollEventsAndWait(); mouseClicked |= _mouseClicked; mouseButtons |= _mouseButtons; diff --git a/engines/sherlock/events.h b/engines/sherlock/events.h index f4e6964ef5..4493fcdc65 100644 --- a/engines/sherlock/events.h +++ b/engines/sherlock/events.h @@ -75,7 +75,9 @@ public: void clearEvents(); - void delay(int amount); + void wait(int numFrames); + + bool delay(uint32 time, bool interruptable = false); void waitForNextFrame(); diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index 2bce822707..a4990fb6c6 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -35,6 +35,13 @@ Surface::~Surface() { free(); } +/** + * Copy a surface into this one + */ +void Surface::blitFrom(const Graphics::Surface &src) { + blitFrom(src, Common::Point(0, 0)); +} + /** * Draws a surface at a given position within this surface */ @@ -59,18 +66,25 @@ void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt) { drawRect.bottom -= (bottom - this->h); } - if (drawRect.isValidRect()) { - addDirtyRect(Common::Rect(destPt.x, destPt.y, destPt.x + drawRect.width(), - destPt.y + drawRect.height())); - copyRectToSurface(src, destPt.x, destPt.y, drawRect); - } + if (drawRect.isValidRect()) + blitFrom(src, destPt, drawRect); } +/** + * Draws a sub-section of a surface at a given position within this surface + */ +void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt, + const Common::Rect &srcBounds) { + addDirtyRect(Common::Rect(pt.x, pt.y, pt.x + srcBounds.width(), + pt.y + srcBounds.height())); + copyRectToSurface(src, pt.x, pt.y, srcBounds); +} /** * Draws a surface at a given position within this surface with transparency */ -void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &pt) { +void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &pt, + bool flipped, int overrideColor) { Common::Rect drawRect(0, 0, src.w, src.h); Common::Point destPt = pt; @@ -94,18 +108,25 @@ void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &p if (!drawRect.isValidRect()) return; + if (flipped) + drawRect = Common::Rect(src.w - drawRect.right, src.h - drawRect.bottom, + src.w - drawRect.left, src.h - drawRect.top); + addDirtyRect(Common::Rect(destPt.x, destPt.y, destPt.x + drawRect.width(), destPt.y + drawRect.height())); // Draw loop const int TRANSPARENCY = 0xFF; for (int yp = 0; yp < drawRect.height(); ++yp) { - const byte *srcP = (const byte *)src.getBasePtr(drawRect.left, drawRect.top + yp); + const byte *srcP = (const byte *)src.getBasePtr( + flipped ? drawRect.right : drawRect.left, drawRect.top + yp); byte *destP = (byte *)getBasePtr(destPt.x, destPt.y + yp); - for (int xp = 0; xp < drawRect.width(); ++xp, ++srcP, ++destP) { + for (int xp = 0; xp < drawRect.width(); ++xp, ++destP) { if (*srcP != TRANSPARENCY) - *destP = *srcP; + *destP = overrideColor ? overrideColor : *srcP; + + srcP = flipped ? srcP - 1 : srcP + 1; } } } diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index 983a22a790..82c48307d7 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -35,8 +35,12 @@ public: Surface(uint16 width, uint16 height); ~Surface(); + void blitFrom(const Graphics::Surface &src); void blitFrom(const Graphics::Surface &src, const Common::Point &pt); - void transBlitFrom(const Graphics::Surface &src, const Common::Point &pt); + void blitFrom(const Graphics::Surface &src, const Common::Point &pt, + const Common::Rect &srcBounds); + void transBlitFrom(const Graphics::Surface &src, const Common::Point &pt, + bool flipped = false, int overrideColor = 0); void fillRect(int x1, int y1, int x2, int y2, byte color); }; diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 90a93de1b1..0e5a3bec34 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -59,15 +59,75 @@ void ScalpelEngine::showOpening() { } bool ScalpelEngine::showCityCutscene() { -// byte palette[PALETTE_SIZE]; + byte palette[PALETTE_SIZE]; _sound->playMusic("prolog1.mus"); _titleOverride = "title.lib"; _soundOverride = "title.snd"; - _animation->playPrologue("26open1", 1, 255, true, 2); - - // TODO - return true; + bool finished = _animation->playPrologue("26open1", 1, 255, true, 2); + + if (finished) { + Sprite titleSprites("title2.vgs", true); + _screen->_backBuffer.blitFrom(*_screen); + _screen->_backBuffer2.blitFrom(*_screen); + + // London, England + _screen->_backBuffer.transBlitFrom(titleSprites[0], Common::Point(10, 11)); + _screen->randomTransition(); + finished = _events->delay(1000, true); + + // November, 1888 + if (finished) { + _screen->_backBuffer.transBlitFrom(titleSprites[1], Common::Point(101, 102)); + _screen->randomTransition(); + finished = _events->delay(5000, true); + } + + // Transition out the title + _screen->_backBuffer.blitFrom(_screen->_backBuffer2); + _screen->randomTransition(); + } + + if (finished) + finished = _animation->playPrologue("26open2", 1, 0, false, 2); + + if (finished) { + Sprite titleSprites("title.vgs", true); + _screen->_backBuffer.blitFrom(*_screen); + _screen->_backBuffer2.blitFrom(*_screen); + + // The Lost Files of + _screen->_backBuffer.transBlitFrom(titleSprites[0], Common::Point(75, 6)); + // Sherlock Holmes + _screen->_backBuffer.transBlitFrom(titleSprites[1], Common::Point(34, 21)); + // copyright + _screen->_backBuffer.transBlitFrom(titleSprites[2], Common::Point(4, 190)); + + _screen->verticalTransition(); + finished = _events->delay(4000, true); + + if (finished) { + _screen->_backBuffer.blitFrom(_screen->_backBuffer2); + _screen->randomTransition(); + finished = _events->delay(2000); + } + + if (finished) { + _screen->getPalette(palette); + _screen->fadeToBlack(2); + } + + if (finished) { + // In the alley... + _screen->transBlitFrom(titleSprites[3], Common::Point(72, 51)); + _screen->fadeIn(palette, 3); + finished = _events->delay(3000, true); + } + } + + _titleOverride = ""; + _soundOverride = ""; + return finished; } bool ScalpelEngine::showAlleyCutscene() { diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 500abc1197..41cf19e48c 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -28,7 +28,7 @@ namespace Sherlock { Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), _vm(vm), - _backBuffer1(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), + _backBuffer(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), _backBuffer2(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT) { setFont(1); } @@ -94,27 +94,30 @@ int Screen::equalizePalette(const byte palette[PALETTE_SIZE]) { return total; } -void Screen::fadeToBlack() { - const int FADE_AMOUNT = 2; - bool repeatFlag; - byte *srcP; - int count; +/** + * Fade out the palette to black + */ +void Screen::fadeToBlack(int speed) { byte tempPalette[PALETTE_SIZE]; + Common::fill(&tempPalette[0], &tempPalette[PALETTE_SIZE], 0); - getPalette(tempPalette); - do { - repeatFlag = false; - for (srcP = &tempPalette[0], count = 0; count < PALETTE_SIZE; ++count, ++srcP) { - int v = *srcP; - if (v) { - repeatFlag = true; - *srcP = MAX(*srcP - FADE_AMOUNT, 0); - } - } + while (equalizePalette(tempPalette)) { + _vm->_events->delay(15 * speed); + } - setPalette(tempPalette); - _vm->_events->pollEventsAndWait(); - } while (repeatFlag && !_vm->shouldQuit()); + setPalette(tempPalette); +} + +/** + * Fade in a given palette + */ +void Screen::fadeIn(const byte palette[PALETTE_SIZE], int speed) { + int count = 50; + while (equalizePalette(palette) && --count) { + _vm->_events->delay(15 * speed); + } + + setPalette(palette); } /** @@ -170,4 +173,50 @@ bool Screen::unionRectangle(Common::Rect &destRect, const Common::Rect &src1, co return !destRect.isEmpty(); } +/** + * Do a random pixel transition in from _backBuffer surface to the screen + */ +void Screen::randomTransition() { + EventsManager &events = *_vm->_events; + + for (int idx = 0; idx <= 65535; ++idx) { + int offset = _vm->getRandomNumber(this->w * this->h); + *((byte *)getPixels() + offset) = *((const byte *)_backBuffer.getPixels() + offset); + + if (idx != 0 && (idx % 100) == 0) { + _dirtyRects.clear(); + addDirtyRect(Common::Rect(0, 0, this->w, this->h)); + events.delay(5); + } + } + + // Make sure everything has been transferred + blitFrom(_backBuffer); +} + +/** + * Transition to the surface from _backBuffer using a vertical transition + */ +void Screen::verticalTransition() { + EventsManager &events = *_vm->_events; + + byte table[SHERLOCK_SCREEN_WIDTH]; + Common::fill(&table[0], &table[SHERLOCK_SCREEN_WIDTH], 0); + + for (int yp = 0; yp < SHERLOCK_SCREEN_HEIGHT; ++yp) { + for (int xp = 0; xp < SHERLOCK_SCREEN_WIDTH; ++xp) { + int temp = (table[xp] >= 197) ? SHERLOCK_SCREEN_HEIGHT - table[xp] : + _vm->getRandomNumber(3) + 1; + + if (temp) { + blitFrom(_backBuffer, Common::Point(xp, table[xp]), + Common::Rect(xp, table[xp], xp + 1, table[xp] + temp)); + table[xp] += temp; + } + } + + events.delay(10); + } +} + } // End of namespace Sherlock diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index d244452771..0c0175d2ed 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -41,7 +41,6 @@ class Screen : public Surface { private: SherlockEngine *_vm; int _fontNumber; - Surface _backBuffer1, _backBuffer2; Common::List _dirtyRects; void mergeDirtyRects(); @@ -49,6 +48,8 @@ private: bool unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2); protected: virtual void addDirtyRect(const Common::Rect &r); +public: + Surface _backBuffer, _backBuffer2; public: Screen(SherlockEngine *vm); @@ -62,7 +63,13 @@ public: int equalizePalette(const byte palette[PALETTE_SIZE]); - void fadeToBlack(); + void fadeToBlack(int speed = 2); + + void fadeIn(const byte palette[PALETTE_SIZE], int speed = 2); + + void randomTransition(); + + void verticalTransition(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 1fba746f8d..add24cba9f 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -29,7 +29,7 @@ namespace Sherlock { SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc) : - Engine(syst), _gameDescription(gameDesc) { + Engine(syst), _gameDescription(gameDesc), _randomSource("Sherlock") { _animation = nullptr; _debugger = nullptr; _events = nullptr; @@ -82,6 +82,7 @@ void SherlockEngine::initialize() { _screen = new Screen(this); _sound = new Sound(this); _talk = new Talk(); + Sprite::setVm(this); } Common::Error SherlockEngine::run() { diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 8d24a78c81..cedc57a9f8 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -26,9 +26,10 @@ #include "common/scummsys.h" #include "common/array.h" #include "common/endian.h" -#include "common/util.h" -#include "common/savefile.h" #include "common/hash-str.h" +#include "common/random.h" +#include "common/savefile.h" +#include "common/util.h" #include "engines/engine.h" #include "sherlock/animation.h" #include "sherlock/debugger.h" @@ -79,6 +80,7 @@ public: Screen *_screen; Sound *_sound; Talk *_talk; + Common::RandomSource _randomSource; Common::Array _flags; Common::String _soundOverride; Common::String _titleOverride; @@ -96,6 +98,8 @@ public: Common::Platform getPlatform() const; Common::String getGameFile(int fileType); + + int getRandomNumber(int limit) { return _randomSource.getRandomNumber(limit - 1); } }; } // End of namespace Sherlock diff --git a/engines/sherlock/sprite.cpp b/engines/sherlock/sprite.cpp index be5a0e0d27..8a7bb4cf29 100644 --- a/engines/sherlock/sprite.cpp +++ b/engines/sherlock/sprite.cpp @@ -22,10 +22,26 @@ #include "sherlock/sprite.h" #include "sherlock/screen.h" +#include "sherlock/sherlock.h" #include "common/debug.h" namespace Sherlock { +SherlockEngine *Sprite::_vm; + +void Sprite::setVm(SherlockEngine *vm) { + _vm = vm; +} + +Sprite::Sprite(const Common::String &name, bool skipPal) { + Common::SeekableReadStream *stream = _vm->_res->load(name); + + Common::fill(&_palette[0], &_palette[PALETTE_SIZE], 0); + load(*stream, skipPal); + + delete stream; +} + Sprite::Sprite(Common::SeekableReadStream &stream, bool skipPal) { Common::fill(&_palette[0], &_palette[PALETTE_SIZE], 0); load(stream, skipPal); @@ -39,7 +55,7 @@ Sprite::~Sprite() { /** * Load the data of the sprite */ -void Sprite::load(Common::SeekableReadStream &stream, bool skipPal) { +void Sprite::load(Common::SeekableReadStream &stream, bool skipPalette) { loadPalette(stream); while (stream.pos() < stream.size()) { @@ -50,7 +66,7 @@ void Sprite::load(Common::SeekableReadStream &stream, bool skipPal) { frame._position.x = stream.readUint16LE(); frame._position.y = stream.readByte(); - frame._rleEncoded = !skipPal && (frame._position.x == 1); + frame._rleEncoded = !skipPalette && (frame._position.x == 1); if (frame._flags & 0xFF) { // Nibble packed frame data @@ -78,15 +94,20 @@ void Sprite::load(Common::SeekableReadStream &stream, bool skipPal) { * Gets the palette at the start of the sprite file */ void Sprite::loadPalette(Common::SeekableReadStream &stream) { - // Read in the palette + // Check for palette int v1 = stream.readUint16LE() + 1; int v2 = stream.readUint16LE() + 1; int size = v1 * v2; - assert((size - 12) == PALETTE_SIZE); - - stream.seek(4 + 12, SEEK_CUR); - for (int idx = 0; idx < PALETTE_SIZE; ++idx) - _palette[idx] = VGA_COLOR_TRANS(stream.readByte()); + + if ((size - 12) == PALETTE_SIZE) { + // Found palette, so read it in + stream.seek(4 + 12, SEEK_CUR); + for (int idx = 0; idx < PALETTE_SIZE; ++idx) + _palette[idx] = VGA_COLOR_TRANS(stream.readByte()); + } else { + // Not a palette, so rewind to start of frame data for normal frame processing + stream.seek(-4, SEEK_CUR); + } } /** diff --git a/engines/sherlock/sprite.h b/engines/sherlock/sprite.h index 8aedbdb9c5..844013db43 100644 --- a/engines/sherlock/sprite.h +++ b/engines/sherlock/sprite.h @@ -30,6 +30,8 @@ namespace Sherlock { +class SherlockEngine; + struct SpriteFrame { uint32 _size; uint16 _width, _height; @@ -38,18 +40,24 @@ struct SpriteFrame { Common::Point _position; byte _rleMarker; Graphics::Surface _frame; + + operator Graphics::Surface &() { return _frame; } }; class Sprite: public Common::Array { private: - void load(Common::SeekableReadStream &stream, bool skipPal); + static SherlockEngine *_vm; + + void load(Common::SeekableReadStream &stream, bool skipPalette); void loadPalette(Common::SeekableReadStream &stream); void decompressFrame(SpriteFrame &frame, const byte *src); public: byte _palette[256 * 3]; public: - Sprite(Common::SeekableReadStream &stream, bool skipPal = false); + Sprite(const Common::String &name, bool skipPal = false); + Sprite(Common::SeekableReadStream &stream, bool skipPal = false); ~Sprite(); + static void setVm(SherlockEngine *vm); }; } // End of namespace Sherlock -- cgit v1.2.3 From b8ad1ce140c91257ba79fe50f41da34a5a6e74c2 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 18 Mar 2015 19:02:17 -0400 Subject: SHERLOCK: Make random pixel transitions more like the original --- engines/sherlock/events.cpp | 34 ++++++++++++++++++++++++---------- engines/sherlock/screen.cpp | 19 ++++++++++++++----- engines/sherlock/screen.h | 1 + 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index c6c013193c..b2d9fc65e8 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -166,18 +166,32 @@ void EventsManager::wait(int numFrames) { } bool EventsManager::delay(uint32 time, bool interruptable) { - uint32 delayEnd = g_system->getMillis() + time; - - while (!_vm->shouldQuit() && g_system->getMillis() < delayEnd) { - pollEventsAndWait(); - - if (interruptable && (isKeyPressed() || _mouseClicked)) { - clearEvents(); - return false; + // Different handling for really short versus extended times + if (time < 10) { + // For really short periods, simply delay by the desired amount + pollEvents(); + g_system->delayMillis(time); + bool result = !(interruptable && (isKeyPressed() || _mouseClicked)); + + clearEvents(); + return result; + } else { + // For long periods go into a loop where we delay by 10ms at a time and then + // check for events. This ensures for longer delays that responsiveness is + // maintained + uint32 delayEnd = g_system->getMillis() + time; + + while (!_vm->shouldQuit() && g_system->getMillis() < delayEnd) { + pollEventsAndWait(); + + if (interruptable && (isKeyPressed() || _mouseClicked)) { + clearEvents(); + return false; + } } - } - return true; + return true; + } } /** diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 41cf19e48c..7a4d4863ac 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -30,6 +30,7 @@ namespace Sherlock { Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), _vm(vm), _backBuffer(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), _backBuffer2(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT) { + _transitionSeed = 1; setFont(1); } @@ -178,15 +179,23 @@ bool Screen::unionRectangle(Common::Rect &destRect, const Common::Rect &src1, co */ void Screen::randomTransition() { EventsManager &events = *_vm->_events; + const int TRANSITION_MULTIPLIER = 0x15a4e35; + _dirtyRects.clear(); for (int idx = 0; idx <= 65535; ++idx) { - int offset = _vm->getRandomNumber(this->w * this->h); - *((byte *)getPixels() + offset) = *((const byte *)_backBuffer.getPixels() + offset); + _transitionSeed = _transitionSeed * TRANSITION_MULTIPLIER + 1; + int offset = _transitionSeed & 65535; + + if (offset < (SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCREEN_HEIGHT)) + *((byte *)getPixels() + offset) = *((const byte *)_backBuffer.getPixels() + offset); if (idx != 0 && (idx % 100) == 0) { - _dirtyRects.clear(); - addDirtyRect(Common::Rect(0, 0, this->w, this->h)); - events.delay(5); + // Ensure there's a full screen dirty rect for the next frame update + if (_dirtyRects.empty()) + addDirtyRect(Common::Rect(0, 0, this->w, this->h)); + + events.pollEvents(); + events.delay(1); } } diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 0c0175d2ed..78ccffc575 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -42,6 +42,7 @@ private: SherlockEngine *_vm; int _fontNumber; Common::List _dirtyRects; + uint32 _transitionSeed; void mergeDirtyRects(); -- cgit v1.2.3 From 2dc355ff6ecbbc3650beecb341ebe4415de20101 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 18 Mar 2015 22:32:41 -0400 Subject: SHERLOCK: Implement Scalpel-specific scene starting --- engines/sherlock/events.cpp | 24 ++++- engines/sherlock/events.h | 10 +- engines/sherlock/resources.cpp | 57 +++++++---- engines/sherlock/resources.h | 3 + engines/sherlock/room.cpp | 2 +- engines/sherlock/room.h | 3 + engines/sherlock/scalpel/scalpel.cpp | 177 +++++++++++++++++++++++++++++++++++ engines/sherlock/scalpel/scalpel.h | 12 ++- engines/sherlock/screen.cpp | 1 + engines/sherlock/screen.h | 1 + engines/sherlock/sherlock.cpp | 16 +++- engines/sherlock/sherlock.h | 4 + engines/sherlock/sound.cpp | 14 +++ engines/sherlock/sound.h | 4 + 14 files changed, 297 insertions(+), 31 deletions(-) diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index b2d9fc65e8..1a882eedea 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -32,7 +32,8 @@ namespace Sherlock { EventsManager::EventsManager(SherlockEngine *vm) { _vm = vm; - _cursorId = CURSOR_NONE; + _cursorSprites = nullptr; + _cursorIndex = -1; _frameCounter = 1; _priorFrameTime = 0; _mouseClicked = false; @@ -40,15 +41,30 @@ EventsManager::EventsManager(SherlockEngine *vm) { } EventsManager::~EventsManager() { + delete _cursorSprites; +} + +/** + * Load a set of cursors from the specified file + */ +void EventsManager::loadCursors(const Common::String &filename) { + hideCursor(); + delete _cursorSprites; + + _cursorSprites = new Sprite(filename); } /** * Set the cursor to show */ -void EventsManager::setCursor(CursorType cursorId) { - _cursorId = cursorId; +void EventsManager::changeCursor(int cursorIndex) { + _cursorIndex = cursorIndex; + + // Set the cursor data + Graphics::Surface &s = (*_cursorSprites)[cursorIndex]; + CursorMan.replaceCursor(s.getPixels(), s.w, s.h, s.w / 2, s.h / 2, 0xff); - // TODO: Cursor handling + showCursor(); } /** diff --git a/engines/sherlock/events.h b/engines/sherlock/events.h index 4493fcdc65..1f7352eeb5 100644 --- a/engines/sherlock/events.h +++ b/engines/sherlock/events.h @@ -26,11 +26,10 @@ #include "common/scummsys.h" #include "common/events.h" #include "common/stack.h" +#include "sherlock/sprite.h" namespace Sherlock { -enum CursorType { CURSOR_NONE = 0 }; - #define GAME_FRAME_RATE 60 #define GAME_FRAME_TIME (1000 / GAME_FRAME_RATE) @@ -42,10 +41,11 @@ private: uint32 _frameCounter; uint32 _priorFrameTime; Common::Point _mousePos; + Sprite *_cursorSprites; bool checkForNextFrameCounter(); public: - CursorType _cursorId; + int _cursorIndex; byte _mouseButtons; bool _mouseClicked; Common::Stack _pendingKeys; @@ -53,7 +53,9 @@ public: EventsManager(SherlockEngine *vm); ~EventsManager(); - void setCursor(CursorType cursorId); + void loadCursors(const Common::String &filename); + + void changeCursor(int cursorIndex); void showCursor(); diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index 47e2046084..6636ca5be8 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -41,43 +41,57 @@ bool Cache::isCached(const Common::String &filename) const { * If the file is LZW compressed, automatically decompresses it and loads * the uncompressed version into memory */ -void Cache::load(const Common::String &filename) { +void Cache::load(const Common::String &name) { // First check if the entry already exists - if (_resources.contains(filename)) + if (_resources.contains(name)) return; - // Allocate a new cache entry - _resources[filename] = CacheEntry(); - CacheEntry &cacheEntry = _resources[filename]; - // Open the file for reading Common::File f; - if (!f.open(filename)) - error("Could not read file - %s", filename.c_str()); + if (!f.open(name)) + error("Could not read file - %s", name.c_str()); + + load(name, f); + + f.close(); +} + +/** + * Load a cache entry based on a passed stream + */ +void Cache::load(const Common::String &name, Common::SeekableReadStream &stream) { + // First check if the entry already exists + if (_resources.contains(name)) + return; // Check whether the file is compressed const char LZW_HEADER[5] = { "LZV\x1a" }; char header[5]; - f.read(header, 5); + stream.read(header, 5); bool isCompressed = !strncmp(header, LZW_HEADER, 5); - f.seek(0); + stream.seek(0); + + // Allocate a new cache entry + _resources[name] = CacheEntry(); + CacheEntry &cacheEntry = _resources[name]; if (isCompressed) { // It's compressed, so decompress the file and store it's data in the cache entry - Common::SeekableReadStream *decompressed = decompressLZ(f); + Common::SeekableReadStream *decompressed = decompressLZ(stream); cacheEntry.resize(decompressed->size()); decompressed->read(&cacheEntry[0], decompressed->size()); delete decompressed; } else { // It's not, so read the raw data of the file into the cache entry - cacheEntry.resize(f.size()); - f.read(&cacheEntry[0], f.size()); + cacheEntry.resize(stream.size()); + stream.read(&cacheEntry[0], stream.size()); } - - f.close(); } +/** + * Get a file from the cache + */ Common::SeekableReadStream *Cache::get(const Common::String &filename) const { // Return a memory stream that encapsulates the data const CacheEntry &cacheEntry = _resources[filename]; @@ -96,7 +110,6 @@ Resources::Resources() { addToCache("portrait.lib"); } - /** * Adds the specified file to the cache. If it's a library file, takes care of * loading it's index for future use @@ -113,6 +126,18 @@ void Resources::addToCache(const Common::String &filename) { delete stream; } +/** + * Adds a resource from a library file tot he cache + */ +void Resources::addToCache(const Common::String &filename, const Common::String &libFilename) { + // Get the resource + Common::SeekableReadStream *stream = load(filename, libFilename); + + _cache.load(filename, *stream); + + delete stream; +} + Common::SeekableReadStream *Resources::load(const Common::String &filename) { // First check if the file is directly in the cache if (_cache.isCached(filename)) diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h index edb9bd8ba0..cd6e60c325 100644 --- a/engines/sherlock/resources.h +++ b/engines/sherlock/resources.h @@ -57,6 +57,7 @@ public: bool isCached(const Common::String &filename) const; void load(const Common::String &name); + void load(const Common::String &name, Common::SeekableReadStream &stream); Common::SeekableReadStream *get(const Common::String &filename) const; }; @@ -72,6 +73,8 @@ public: Resources(); void addToCache(const Common::String &filename); + void addToCache(const Common::String &filename, const Common::String &libFilename); + bool isInCache(const Common::String &filename) const { return _cache.isCached(filename); } Common::SeekableReadStream *load(const Common::String &filename); diff --git a/engines/sherlock/room.cpp b/engines/sherlock/room.cpp index 9926899953..c06d707b40 100644 --- a/engines/sherlock/room.cpp +++ b/engines/sherlock/room.cpp @@ -27,8 +27,8 @@ namespace Sherlock { Rooms::Rooms() { for (int roomNum = 0; roomNum < ROOMS_COUNT; ++roomNum) Common::fill(&_stats[roomNum][0], &_stats[roomNum][9], false); - _goToRoom = -1; + _oldCharPoint = 0; } } // End of namespace Sherlock diff --git a/engines/sherlock/room.h b/engines/sherlock/room.h index 75800b623a..0f2bc56a45 100644 --- a/engines/sherlock/room.h +++ b/engines/sherlock/room.h @@ -94,6 +94,9 @@ public: bool _stats[ROOMS_COUNT][9]; bool _savedStats[ROOMS_COUNT][9]; int _goToRoom; + Common::Point _bigPos; + Common::Point _overPos; + int _oldCharPoint; public: Rooms(); }; diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 0e5a3bec34..d691bbd8bb 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -27,6 +27,12 @@ namespace Sherlock { namespace Scalpel { +ScalpelEngine::ScalpelEngine(OSystem *syst, const SherlockGameDescription *gameDesc) : + SherlockEngine(syst, gameDesc) { + _tempFadeStyle = 0; + _chessResult = 0; +} + /** * Game initialization */ @@ -131,17 +137,188 @@ bool ScalpelEngine::showCityCutscene() { } bool ScalpelEngine::showAlleyCutscene() { + // TODO return true; } bool ScalpelEngine::showStreetCutscene() { + // TODO return true; } bool ScalpelEngine::showOfficeCutscene() { + // TODO return true; } +int ScalpelEngine::doChessBoard() { + // TODO + return 0; +} + +void ScalpelEngine::playDarts() { + // TODO +} + +/** + * Starting a scene within the game + */ +void ScalpelEngine::startScene() { + if (_rooms->_goToRoom == 100 || _rooms->_goToRoom == 98) { + // Chessboard selection + if (_sound->_musicEnabled) { + if (_sound->loadSong(100)) { + if (_sound->_music) + _sound->startSong(); + } + } + + _rooms->_goToRoom = doChessBoard(); + + _sound->freeSong(); + _hsavedPos = Common::Point(-1, -1); + _hsavedFs = -1; + } + + // Some rooms are prologue cutscenes, rather than normal game scenes. These are: + // 2: Blackwood's capture + // 52: Rescuing Anna + // 53: Moorehead's death / subway train + // 55: Fade out and exit + // 70: Brumwell suicide + switch (_rooms->_goToRoom) { + case 2: + case 52: + case 53: + case 70: + if (_sound->_musicEnabled && _sound->loadSong(_rooms->_goToRoom)) { + if (_sound->_music) + _sound->startSong(); + } + + switch (_rooms->_goToRoom) { + case 2: + // Blackwood's capture + _res->addToCache("final2.vda", "epilogue.lib"); + _res->addToCache("final2.vdx", "epilogue.lib"); + _animation->playPrologue("final1", 1, 3, true, 4); + _animation->playPrologue("final22", 1, 0, false, 4); + break; + + case 52: + // Rescuing Anna + _res->addToCache("finalr2.vda", "epilogue.lib"); + _res->addToCache("finalr2.vdx", "epilogue.lib"); + _res->addToCache("finale1.vda", "epilogue.lib"); + _res->addToCache("finale1.vdx", "epilogue.lib"); + _res->addToCache("finale2.vda", "epilogue.lib"); + _res->addToCache("finale2.vdx", "epilogue.lib"); + _res->addToCache("finale3.vda", "epilogue.lib"); + _res->addToCache("finale3.vdx", "epilogue.lib"); + _res->addToCache("finale4.vda", "EPILOG2.lib"); + _res->addToCache("finale4.vdx", "EPILOG2.lib"); + + _animation->playPrologue("finalr1", 1, 3, true, 4); + _animation->playPrologue("finalr2", 1, 0, false, 4); + + if (!_res->isInCache("finale2.vda")) { + // Finale file isn't cached + _res->addToCache("finale2.vda", "epilogue.lib"); + _res->addToCache("finale2.vdx", "epilogue.lib"); + _res->addToCache("finale3.vda", "epilogue.lib"); + _res->addToCache("finale3.vdx", "epilogue.lib"); + _res->addToCache("finale4.vda", "EPILOG2.lib"); + _res->addToCache("finale4.vdx", "EPILOG2.lib"); + } + + _animation->playPrologue("finale1", 1, 0, false, 4); + _animation->playPrologue("finale2", 1, 0, false, 4); + _animation->playPrologue("finale3", 1, 0, false, 4); + + _useEpilogue2 = true; + _animation->playPrologue("finale4", 1, 0, false, 4); + _useEpilogue2 = false; + break; + + case 53: + // Moorehead's death / subway train + _res->addToCache("SUBWAY2.vda", "epilogue.lib"); + _res->addToCache("SUBWAY2.vdx", "epilogue.lib"); + _res->addToCache("SUBWAY3.vda", "epilogue.lib"); + _res->addToCache("SUBWAY3.vdx", "epilogue.lib"); + + _animation->playPrologue("SUBWAY1", 1, 3, true, 4); + _animation->playPrologue("SUBWAY2", 1, 0, false, 4); + _animation->playPrologue("SUBWAY3", 1, 0, false, 4); + + // Set fading to direct fade temporary so the transition goes quickly. + _tempFadeStyle = _screen->_fadeStyle ? 257 : 256; + _screen->_fadeStyle = false; + break; + + case 70: + // Brumwell suicide + _animation->playPrologue("suicid", 1, 3, true, 4); + break; + default: + break; + } + + // Except for the Moorehead Murder scene, fade to black first + if (_rooms->_goToRoom != 53) { + _events->wait(40); + _screen->fadeToBlack(3); + } + + switch (_rooms->_goToRoom) { + case 52: + _rooms->_goToRoom = 27; // Go to the Lawyer's Office + _rooms->_bigPos = Common::Point(0, 0); // Overland scroll position + _rooms->_overPos = Common::Point(22900 - 600, 9400 + 900); // Overland position + _rooms->_oldCharPoint = 27; + break; + + case 53: + _rooms->_goToRoom = 17; // Go to St. Pancras Station + _rooms->_bigPos = Common::Point(0, 0); // Overland scroll position + _rooms->_overPos = Common::Point(32500 - 600, 3000 + 900); // Overland position + _rooms->_oldCharPoint = 17; + break; + + default: + _rooms->_goToRoom = 4; // Back to Baker st. + _rooms->_bigPos = Common::Point(0, 0); // Overland scroll position + _rooms->_overPos = Common::Point(14500 - 600, 8400 + 900); // Overland position + _rooms->_oldCharPoint = 4; + break; + } + + // Free any song from the previous scene + _sound->freeSong(); + break; + + case 55: + // Exit game + _screen->fadeToBlack(3); + quitGame(); + return; + + default: + break; + } + + _events->loadCursors("rmouse.vgs"); + _events->changeCursor(0); + + if (_rooms->_goToRoom == 99) { + // Chess Board + playDarts(); + _chessResult = _rooms->_goToRoom = 19; // Go back to the bar + } + + _chessResult = _rooms->_goToRoom; +} + } // End of namespace Scalpel } // End of namespace Scalpel diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h index 584bd78a20..83510064fa 100644 --- a/engines/sherlock/scalpel/scalpel.h +++ b/engines/sherlock/scalpel/scalpel.h @@ -31,17 +31,25 @@ namespace Scalpel { class ScalpelEngine : public SherlockEngine { private: + int _tempFadeStyle; + int _chessResult; + bool showCityCutscene(); bool showAlleyCutscene(); bool showStreetCutscene(); bool showOfficeCutscene(); + + int doChessBoard(); + + void playDarts(); protected: virtual void initialize(); virtual void showOpening(); + + virtual void startScene(); public: - ScalpelEngine(OSystem *syst, const SherlockGameDescription *gameDesc) : - SherlockEngine(syst, gameDesc) {} + ScalpelEngine(OSystem *syst, const SherlockGameDescription *gameDesc); virtual ~ScalpelEngine() {} }; diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 7a4d4863ac..0ec5df9c4c 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -31,6 +31,7 @@ Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCR _backBuffer(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), _backBuffer2(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT) { _transitionSeed = 1; + _fadeStyle = false; setFont(1); } diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 78ccffc575..05fd80a8b7 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -51,6 +51,7 @@ protected: virtual void addDirtyRect(const Common::Rect &r); public: Surface _backBuffer, _backBuffer2; + bool _fadeStyle; public: Screen(SherlockEngine *vm); diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index add24cba9f..907f0a5a16 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -40,9 +40,10 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _sound = nullptr; _talk = nullptr; _useEpilogue2 = false; + _hsavedPos = Common::Point(-1, -1); + _hsavedFs = -1; } - SherlockEngine::~SherlockEngine() { delete _animation; delete _debugger; @@ -73,11 +74,11 @@ void SherlockEngine::initialize() { _midi->setNativeMT32(native_mt32); */ + _res = new Resources(); _animation = new Animation(this); _debugger = new Debugger(this); _events = new EventsManager(this); _journal = new Journal(); - _res = new Resources(); _rooms = new Rooms(); _screen = new Screen(this); _sound = new Sound(this); @@ -90,8 +91,15 @@ Common::Error SherlockEngine::run() { showOpening(); - // TODO: Rest of game - + while (!shouldQuit()) { + // Prepare for scene, and handle any game-specific scenes + startScene(); + + // TODO: Implement game and remove this dummy loop + while (!shouldQuit()) + _events->pollEventsAndWait(); + } + return Common::kNoError; } diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index cedc57a9f8..7906417d7e 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -69,6 +69,8 @@ protected: virtual void initialize(); virtual void showOpening() = 0; + + virtual void startScene() {} public: const SherlockGameDescription *_gameDescription; Animation *_animation; @@ -85,6 +87,8 @@ public: Common::String _soundOverride; Common::String _titleOverride; bool _useEpilogue2; + Common::Point _hsavedPos; + int _hsavedFs; public: SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc); virtual ~SherlockEngine(); diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index 0957315a35..efc1965637 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -29,6 +29,7 @@ Sound::Sound(SherlockEngine *vm): _vm(vm) { _musicEnabled = true; _voicesEnabled = true; _playingEpilogue = false; + _music = false; } void Sound::playSound(const Common::String &name, WaitType waitType) { @@ -59,5 +60,18 @@ void Sound::stopMusic() { // TODO } +int Sound::loadSong(int songNumber) { + // TODO + return 0; +} + +void Sound::startSong() { + // TODO +} + +void Sound::freeSong() { + // TODO +} + } // End of namespace Sherlock diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index 7775016c94..442e908838 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -42,6 +42,7 @@ public: bool _musicEnabled; bool _voicesEnabled; bool _playingEpilogue; + bool _music; public: Sound(SherlockEngine *vm); @@ -50,6 +51,9 @@ public: void playCachedSound(int index); void clearCache(); void stopSound(); + int loadSong(int songNumber); + void startSong(); + void freeSong(); void playMusic(const Common::String &name); void stopMusic(); -- cgit v1.2.3 From 5a7ea9318d54bd725dd2493277dc0daf17f8abb4 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 18 Mar 2015 23:01:47 -0400 Subject: SHERLOCK: Refactor Rooms to Scene, added skeletons for Chess and Darts --- engines/sherlock/debugger.cpp | 2 +- engines/sherlock/module.mk | 4 +- engines/sherlock/room.cpp | 34 ----------- engines/sherlock/room.h | 106 ----------------------------------- engines/sherlock/scalpel/chess.cpp | 37 ++++++++++++ engines/sherlock/scalpel/chess.h | 45 +++++++++++++++ engines/sherlock/scalpel/darts.cpp | 36 ++++++++++++ engines/sherlock/scalpel/darts.h | 45 +++++++++++++++ engines/sherlock/scalpel/scalpel.cpp | 69 ++++++++++++----------- engines/sherlock/scalpel/scalpel.h | 10 ++-- engines/sherlock/scene.cpp | 41 ++++++++++++++ engines/sherlock/scene.h | 55 ++++++++++++++++++ engines/sherlock/sherlock.cpp | 8 ++- engines/sherlock/sherlock.h | 4 +- 14 files changed, 310 insertions(+), 186 deletions(-) delete mode 100644 engines/sherlock/room.cpp delete mode 100644 engines/sherlock/room.h create mode 100644 engines/sherlock/scalpel/chess.cpp create mode 100644 engines/sherlock/scalpel/chess.h create mode 100644 engines/sherlock/scalpel/darts.cpp create mode 100644 engines/sherlock/scalpel/darts.h create mode 100644 engines/sherlock/scene.cpp create mode 100644 engines/sherlock/scene.h diff --git a/engines/sherlock/debugger.cpp b/engines/sherlock/debugger.cpp index 50300322ef..1e0716c3d3 100644 --- a/engines/sherlock/debugger.cpp +++ b/engines/sherlock/debugger.cpp @@ -51,7 +51,7 @@ bool Debugger::cmd_scene(int argc, const char **argv) { debugPrintf("Format: scene \n"); return true; } else { - _vm->_rooms->_goToRoom = strToInt(argv[1]); + _vm->_scene->_goToRoom = strToInt(argv[1]); return false; } } diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk index 06186f1504..eef27aa0b1 100644 --- a/engines/sherlock/module.mk +++ b/engines/sherlock/module.mk @@ -1,6 +1,8 @@ MODULE := engines/sherlock MODULE_OBJS = \ + scalpel/chess.o \ + scalpel/darts.o \ scalpel/scalpel.o \ tattoo/tattoo.o \ animation.o \ @@ -11,7 +13,7 @@ MODULE_OBJS = \ graphics.o \ journal.o \ resources.o \ - room.o \ + scene.o \ screen.o \ sherlock.o \ sound.o \ diff --git a/engines/sherlock/room.cpp b/engines/sherlock/room.cpp deleted file mode 100644 index c06d707b40..0000000000 --- a/engines/sherlock/room.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "sherlock/room.h" - -namespace Sherlock { - -Rooms::Rooms() { - for (int roomNum = 0; roomNum < ROOMS_COUNT; ++roomNum) - Common::fill(&_stats[roomNum][0], &_stats[roomNum][9], false); - _goToRoom = -1; - _oldCharPoint = 0; -} - -} // End of namespace Sherlock diff --git a/engines/sherlock/room.h b/engines/sherlock/room.h deleted file mode 100644 index 0f2bc56a45..0000000000 --- a/engines/sherlock/room.h +++ /dev/null @@ -1,106 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef SHERLOCK_ROOM_H -#define SHERLOCK_ROOM_H - -#include "common/scummsys.h" -#include "sherlock/sprite.h" - -namespace Sherlock { - -#define ROOMS_COUNT 63 - -/* -struct RoomBounds { - int x, y, width, height; -}; - -struct BgshapeSub { - uint16 value; -}; - -struct Bgshape { - char name[12]; - char description[41]; - char *textBufferPtr; - byte *seqBufPtr; - Sprite *sprite; - SpriteFrame *spriteFrame; - byte byte05; - byte seqBigCountFlag; - int16 seqIndex; - int16 canimIndex; - int16 x, y; - int16 xIncr, yIncr, - uint16 status; - int16 x2, y2; - int16 width2, height2; - uint16 word02; - uint16 word03; - byte flag; - byte itemValue; - uint16 word01; - uint16 word05; - uint16 stringIndex; - int16 width, height; - uint16 word04; - byte flagsAndIndex; - uint16 frameCount; - byte spriteFlags; - char string1[50]; - byte byte07; - byte byte01; - byte byte02; - int16 boundsX, boundsY; - byte direction; - byte animIndex; - char string2[50]; - byte byte06; - byte seqByte; - uint16 textBufferOfs; - byte byte03; - uint16 framesCopyCount; - byte byte08; - char string3[51]; - uint16 word06; - uint16 word07; - uint16 word08; - uint16 word09; - BgshapeSub subItems[4]; -}; -*/ -class Rooms { -public: - bool _stats[ROOMS_COUNT][9]; - bool _savedStats[ROOMS_COUNT][9]; - int _goToRoom; - Common::Point _bigPos; - Common::Point _overPos; - int _oldCharPoint; -public: - Rooms(); -}; - -} // End of namespace Sherlock - -#endif diff --git a/engines/sherlock/scalpel/chess.cpp b/engines/sherlock/scalpel/chess.cpp new file mode 100644 index 0000000000..95c662dd01 --- /dev/null +++ b/engines/sherlock/scalpel/chess.cpp @@ -0,0 +1,37 @@ +/* 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 "sherlock/scalpel/chess.h" +#include "sherlock/scalpel/scalpel.h" + +namespace Sherlock { + +namespace Scalpel { + +int Chess::doChessBoard() { + // TODO + return 0; +} + +} // End of namespace Scalpel + +} // End of namespace Scalpel diff --git a/engines/sherlock/scalpel/chess.h b/engines/sherlock/scalpel/chess.h new file mode 100644 index 0000000000..70607472c2 --- /dev/null +++ b/engines/sherlock/scalpel/chess.h @@ -0,0 +1,45 @@ +/* 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 SHERLOCK_CHESS_H +#define SHERLOCK_CHESS_H + +namespace Sherlock { + +namespace Scalpel { + +class ScalpelEngine; + +class Chess { +private: + ScalpelEngine *_vm; +public: + Chess(ScalpelEngine *vm) : _vm(vm) {} + + int doChessBoard(); +}; + +} // End of namespace Scalpel + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/scalpel/darts.cpp b/engines/sherlock/scalpel/darts.cpp new file mode 100644 index 0000000000..857ac63f8c --- /dev/null +++ b/engines/sherlock/scalpel/darts.cpp @@ -0,0 +1,36 @@ +/* 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 "sherlock/scalpel/darts.h" +#include "sherlock/scalpel/scalpel.h" + +namespace Sherlock { + +namespace Scalpel { + +void Darts::playDarts() { + // TODO +} + +} // End of namespace Scalpel + +} // End of namespace Scalpel diff --git a/engines/sherlock/scalpel/darts.h b/engines/sherlock/scalpel/darts.h new file mode 100644 index 0000000000..22164156c9 --- /dev/null +++ b/engines/sherlock/scalpel/darts.h @@ -0,0 +1,45 @@ +/* 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 SHERLOCK_DARTS_H +#define SHERLOCK_DARTS_H + +namespace Sherlock { + +namespace Scalpel { + +class ScalpelEngine; + +class Darts { +private: + ScalpelEngine *_vm; +public: + Darts(ScalpelEngine *vm) : _vm(vm) {} + + void playDarts(); +}; + +} // End of namespace Scalpel + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index d691bbd8bb..d5f63b9c0d 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -29,22 +29,32 @@ namespace Scalpel { ScalpelEngine::ScalpelEngine(OSystem *syst, const SherlockGameDescription *gameDesc) : SherlockEngine(syst, gameDesc) { + _chess = nullptr; + _darts = nullptr; _tempFadeStyle = 0; _chessResult = 0; } +ScalpelEngine::~ScalpelEngine() { + delete _chess; + delete _darts; +} + /** * Game initialization */ void ScalpelEngine::initialize() { SherlockEngine::initialize(); + _chess = new Chess(this); + _darts = new Darts(this); + _flags.resize(100 * 8); _flags[3] = true; // Turn on Alley _flags[39] = true; // Turn on Baker Street - // Starting room - _rooms->_goToRoom = 4; + // Starting scene + _scene->_goToRoom = 4; } /** @@ -151,20 +161,11 @@ bool ScalpelEngine::showOfficeCutscene() { return true; } -int ScalpelEngine::doChessBoard() { - // TODO - return 0; -} - -void ScalpelEngine::playDarts() { - // TODO -} - /** * Starting a scene within the game */ void ScalpelEngine::startScene() { - if (_rooms->_goToRoom == 100 || _rooms->_goToRoom == 98) { + if (_scene->_goToRoom == 100 || _scene->_goToRoom == 98) { // Chessboard selection if (_sound->_musicEnabled) { if (_sound->loadSong(100)) { @@ -173,7 +174,7 @@ void ScalpelEngine::startScene() { } } - _rooms->_goToRoom = doChessBoard(); + _scene->_goToRoom = _chess->doChessBoard(); _sound->freeSong(); _hsavedPos = Common::Point(-1, -1); @@ -186,17 +187,17 @@ void ScalpelEngine::startScene() { // 53: Moorehead's death / subway train // 55: Fade out and exit // 70: Brumwell suicide - switch (_rooms->_goToRoom) { + switch (_scene->_goToRoom) { case 2: case 52: case 53: case 70: - if (_sound->_musicEnabled && _sound->loadSong(_rooms->_goToRoom)) { + if (_sound->_musicEnabled && _sound->loadSong(_scene->_goToRoom)) { if (_sound->_music) _sound->startSong(); } - switch (_rooms->_goToRoom) { + switch (_scene->_goToRoom) { case 2: // Blackwood's capture _res->addToCache("final2.vda", "epilogue.lib"); @@ -265,31 +266,31 @@ void ScalpelEngine::startScene() { } // Except for the Moorehead Murder scene, fade to black first - if (_rooms->_goToRoom != 53) { + if (_scene->_goToRoom != 53) { _events->wait(40); _screen->fadeToBlack(3); } - switch (_rooms->_goToRoom) { + switch (_scene->_goToRoom) { case 52: - _rooms->_goToRoom = 27; // Go to the Lawyer's Office - _rooms->_bigPos = Common::Point(0, 0); // Overland scroll position - _rooms->_overPos = Common::Point(22900 - 600, 9400 + 900); // Overland position - _rooms->_oldCharPoint = 27; + _scene->_goToRoom = 27; // Go to the Lawyer's Office + _scene->_bigPos = Common::Point(0, 0); // Overland scroll position + _scene->_overPos = Common::Point(22900 - 600, 9400 + 900); // Overland position + _scene->_oldCharPoint = 27; break; case 53: - _rooms->_goToRoom = 17; // Go to St. Pancras Station - _rooms->_bigPos = Common::Point(0, 0); // Overland scroll position - _rooms->_overPos = Common::Point(32500 - 600, 3000 + 900); // Overland position - _rooms->_oldCharPoint = 17; + _scene->_goToRoom = 17; // Go to St. Pancras Station + _scene->_bigPos = Common::Point(0, 0); // Overland scroll position + _scene->_overPos = Common::Point(32500 - 600, 3000 + 900); // Overland position + _scene->_oldCharPoint = 17; break; default: - _rooms->_goToRoom = 4; // Back to Baker st. - _rooms->_bigPos = Common::Point(0, 0); // Overland scroll position - _rooms->_overPos = Common::Point(14500 - 600, 8400 + 900); // Overland position - _rooms->_oldCharPoint = 4; + _scene->_goToRoom = 4; // Back to Baker st. + _scene->_bigPos = Common::Point(0, 0); // Overland scroll position + _scene->_overPos = Common::Point(14500 - 600, 8400 + 900); // Overland position + _scene->_oldCharPoint = 4; break; } @@ -310,13 +311,13 @@ void ScalpelEngine::startScene() { _events->loadCursors("rmouse.vgs"); _events->changeCursor(0); - if (_rooms->_goToRoom == 99) { + if (_scene->_goToRoom == 99) { // Chess Board - playDarts(); - _chessResult = _rooms->_goToRoom = 19; // Go back to the bar + _darts->playDarts(); + _chessResult = _scene->_goToRoom = 19; // Go back to the bar } - _chessResult = _rooms->_goToRoom; + _chessResult = _scene->_goToRoom; } } // End of namespace Scalpel diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h index 83510064fa..b096599ee1 100644 --- a/engines/sherlock/scalpel/scalpel.h +++ b/engines/sherlock/scalpel/scalpel.h @@ -24,6 +24,8 @@ #define SHERLOCK_SCALPEL_H #include "sherlock/sherlock.h" +#include "sherlock/scalpel/chess.h" +#include "sherlock/scalpel/darts.h" namespace Sherlock { @@ -31,6 +33,8 @@ namespace Scalpel { class ScalpelEngine : public SherlockEngine { private: + Chess *_chess; + Darts *_darts; int _tempFadeStyle; int _chessResult; @@ -38,10 +42,6 @@ private: bool showAlleyCutscene(); bool showStreetCutscene(); bool showOfficeCutscene(); - - int doChessBoard(); - - void playDarts(); protected: virtual void initialize(); @@ -50,7 +50,7 @@ protected: virtual void startScene(); public: ScalpelEngine(OSystem *syst, const SherlockGameDescription *gameDesc); - virtual ~ScalpelEngine() {} + virtual ~ScalpelEngine(); }; } // End of namespace Scalpel diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp new file mode 100644 index 0000000000..de351a5561 --- /dev/null +++ b/engines/sherlock/scene.cpp @@ -0,0 +1,41 @@ +/* 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 "sherlock/scene.h" + +namespace Sherlock { + +Scene::Scene(SherlockEngine *vm): _vm(vm) { + for (int idx = 0; idx < SCENES_COUNT; ++idx) + Common::fill(&_stats[idx][0], &_stats[idx][9], false); + _goToRoom = -1; + _oldCharPoint = 0; + _numExits = 0; + + _controlSprites = new Sprite("menu.all"); +} + +Scene::~Scene() { + delete _controlSprites; +} + +} // End of namespace Sherlock diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h new file mode 100644 index 0000000000..031245b122 --- /dev/null +++ b/engines/sherlock/scene.h @@ -0,0 +1,55 @@ +/* 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 SHERLOCK_SCENE_H +#define SHERLOCK_SCENE_H + +#include "common/scummsys.h" +#include "sherlock/sprite.h" + +namespace Sherlock { + +#define SCENES_COUNT 63 + +class SherlockEngine; + +class Scene { +private: + SherlockEngine *_vm; +public: + bool _stats[SCENES_COUNT][9]; + bool _savedStats[SCENES_COUNT][9]; + int _goToRoom; + Common::Point _bigPos; + Common::Point _overPos; + int _oldCharPoint; + Sprite *_controlSprites; + int _numExits; +public: + Scene(SherlockEngine *vm); + + ~Scene(); +}; + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 907f0a5a16..8b597df31b 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -35,7 +35,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _events = nullptr; _journal = nullptr; _res = nullptr; - _rooms = nullptr; + _scene = nullptr; _screen = nullptr; _sound = nullptr; _talk = nullptr; @@ -50,7 +50,7 @@ SherlockEngine::~SherlockEngine() { delete _events; delete _journal; delete _res; - delete _rooms; + delete _scene; delete _screen; delete _sound; delete _talk; @@ -79,7 +79,7 @@ void SherlockEngine::initialize() { _debugger = new Debugger(this); _events = new EventsManager(this); _journal = new Journal(); - _rooms = new Rooms(); + _scene = new Scene(this); _screen = new Screen(this); _sound = new Sound(this); _talk = new Talk(); @@ -94,6 +94,8 @@ Common::Error SherlockEngine::run() { while (!shouldQuit()) { // Prepare for scene, and handle any game-specific scenes startScene(); + if (shouldQuit()) + break; // TODO: Implement game and remove this dummy loop while (!shouldQuit()) diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 7906417d7e..c6023684b4 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -36,7 +36,7 @@ #include "sherlock/events.h" #include "sherlock/journal.h" #include "sherlock/resources.h" -#include "sherlock/room.h" +#include "sherlock/scene.h" #include "sherlock/screen.h" #include "sherlock/sound.h" #include "sherlock/talk.h" @@ -78,7 +78,7 @@ public: EventsManager *_events; Journal *_journal; Resources *_res; - Rooms *_rooms; + Scene *_scene; Screen *_screen; Sound *_sound; Talk *_talk; -- cgit v1.2.3 From a02461fcb15da3b2e7e91d9cfb1bca559a1d277b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 19 Mar 2015 19:49:42 -0400 Subject: SHERLOCK: Refactorings, new Sprite and People classes --- engines/sherlock/animation.cpp | 23 +++--- engines/sherlock/events.cpp | 10 +-- engines/sherlock/events.h | 4 +- engines/sherlock/module.mk | 3 +- engines/sherlock/people.cpp | 73 +++++++++++++++++ engines/sherlock/people.h | 57 ++++++++++++++ engines/sherlock/resources.cpp | 121 ++++++++++++++++++++++++++++ engines/sherlock/resources.h | 29 +++++++ engines/sherlock/scalpel/scalpel.cpp | 16 ++-- engines/sherlock/scene.cpp | 19 ++++- engines/sherlock/scene.h | 13 +++- engines/sherlock/sherlock.cpp | 5 +- engines/sherlock/sherlock.h | 2 + engines/sherlock/sprite.cpp | 147 ----------------------------------- engines/sherlock/sprite.h | 65 ---------------- engines/sherlock/sprites.cpp | 27 +++++++ engines/sherlock/sprites.h | 83 ++++++++++++++++++++ 17 files changed, 451 insertions(+), 246 deletions(-) create mode 100644 engines/sherlock/people.cpp create mode 100644 engines/sherlock/people.h delete mode 100644 engines/sherlock/sprite.cpp delete mode 100644 engines/sherlock/sprite.h create mode 100644 engines/sherlock/sprites.cpp create mode 100644 engines/sherlock/sprites.h diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 6788cc51d7..2b12005079 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -22,7 +22,6 @@ #include "sherlock/animation.h" #include "sherlock/sherlock.h" -#include "sherlock/sprite.h" #include "common/algorithm.h" namespace Sherlock { @@ -95,7 +94,7 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f // Load initial image Common::String vdaName = baseName + ".vda"; - Sprite sprite(vdaName, true); + ImageFile images(vdaName, true); events.wait(minDelay); if (fade != 0 && fade != 255) @@ -103,37 +102,37 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f if (setPalette) { if (fade != 255) - screen.setPalette(sprite._palette); + screen.setPalette(images._palette); } int frameNumber = 0; - int spriteFrame; + int imageFrame; Common::Point pt; bool skipped = false; while (!_vm->shouldQuit()) { // Get the next sprite to display - spriteFrame = stream->readSint16LE(); + imageFrame = stream->readSint16LE(); - if (spriteFrame == -2) { + if (imageFrame == -2) { // End of animation reached break; - } else if (spriteFrame != -1) { + } else if (imageFrame != -1) { // Read position from either animation stream or the sprite frame itself - if (spriteFrame < 0) { - spriteFrame += 32769; + if (imageFrame < 0) { + imageFrame += 32769; pt.x = stream->readUint16LE(); pt.y = stream->readUint16LE(); } else { - pt = sprite[spriteFrame]._position; + pt = images[imageFrame]._position; } // Draw the sprite - screen.transBlitFrom(sprite[spriteFrame]._frame, pt); + screen.transBlitFrom(images[imageFrame]._frame, pt); } else { // No sprite to show for this animation frame if (fade == 255) { // Gradual fade in - if (screen.equalizePalette(sprite._palette) == 0) + if (screen.equalizePalette(images._palette) == 0) fade = 0; } diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index 1a882eedea..ecdbdbe8d7 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -32,7 +32,7 @@ namespace Sherlock { EventsManager::EventsManager(SherlockEngine *vm) { _vm = vm; - _cursorSprites = nullptr; + _cursorImages = nullptr; _cursorIndex = -1; _frameCounter = 1; _priorFrameTime = 0; @@ -41,7 +41,7 @@ EventsManager::EventsManager(SherlockEngine *vm) { } EventsManager::~EventsManager() { - delete _cursorSprites; + delete _cursorImages; } /** @@ -49,9 +49,9 @@ EventsManager::~EventsManager() { */ void EventsManager::loadCursors(const Common::String &filename) { hideCursor(); - delete _cursorSprites; + delete _cursorImages; - _cursorSprites = new Sprite(filename); + _cursorImages = new ImageFile(filename); } /** @@ -61,7 +61,7 @@ void EventsManager::changeCursor(int cursorIndex) { _cursorIndex = cursorIndex; // Set the cursor data - Graphics::Surface &s = (*_cursorSprites)[cursorIndex]; + Graphics::Surface &s = (*_cursorImages)[cursorIndex]; CursorMan.replaceCursor(s.getPixels(), s.w, s.h, s.w / 2, s.h / 2, 0xff); showCursor(); diff --git a/engines/sherlock/events.h b/engines/sherlock/events.h index 1f7352eeb5..0fa6bf3a5e 100644 --- a/engines/sherlock/events.h +++ b/engines/sherlock/events.h @@ -26,7 +26,7 @@ #include "common/scummsys.h" #include "common/events.h" #include "common/stack.h" -#include "sherlock/sprite.h" +#include "sherlock/resources.h" namespace Sherlock { @@ -41,7 +41,7 @@ private: uint32 _frameCounter; uint32 _priorFrameTime; Common::Point _mousePos; - Sprite *_cursorSprites; + ImageFile *_cursorImages; bool checkForNextFrameCounter(); public: diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk index eef27aa0b1..865b422ef9 100644 --- a/engines/sherlock/module.mk +++ b/engines/sherlock/module.mk @@ -12,12 +12,13 @@ MODULE_OBJS = \ events.o \ graphics.o \ journal.o \ + people.o \ resources.o \ scene.o \ screen.o \ sherlock.o \ sound.o \ - sprite.o \ + sprites.o \ talk.o # This module can be built as a plugin diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp new file mode 100644 index 0000000000..53ccaf5baf --- /dev/null +++ b/engines/sherlock/people.cpp @@ -0,0 +1,73 @@ +/* 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 "sherlock/people.h" + +namespace Sherlock { + +// Characer animation sequences +static const uint8 CHARACTER_SEQUENCES[MAX_HOLMES_SEQUENCE][MAX_FRAME] = { + { 29, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Right + { 22, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Down + { 29, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Left + { 15, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Up + { 42, 1, 2, 3, 4, 5, 0 }, // Goto Stand Right + { 47, 1, 2, 3, 4, 5, 0 }, // Goto Stand Down + { 42, 1, 2, 3, 4, 5, 0 }, // Goto Stand Left + { 36, 1, 0 }, // Goto Stand Up + { 8, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Up Right + { 1, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Down Right + { 8, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Up Left + { 1, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Down Left + { 37, 1, 2, 3, 4, 5, 0 }, // Goto Stand Up Right + { 37, 1, 2, 3, 4, 5, 0 }, // Goto Stand Up Left + { 52, 1, 2, 3, 4, 0 }, // Goto Stand Down Right + { 52, 1, 2, 3, 4, 0 } // Goto Stand Down Left +}; + + +People::People(SherlockEngine *vm) : _vm(vm) { +} + +void People::reset() { + Sprite &p = _data[PLAYER]; + + p._description = "Sherlock Holmes!"; + p._type = CHARACTER; + p._position = Common::Point(10000, 11000); + p._sequenceNumber = STOP_DOWNRIGHT; + p._sequences = &CHARACTER_SEQUENCES; + p._spriteFrame = nullptr; + p._frameNumber = 1; + p._movement = Common::Point(0, 0); + p._oldPosition = Common::Point(0, 0); + p._oldSize = Common::Point(0, 0); + p._misc = 0; + p._walkCount = 0; + p._pickUp = ""; + p._allow = 0; + p._noShapeSize = Common::Point(0, 0); + p._goto = Common::Point(0, 0); + p._status = 0; +} + +} // End of namespace Sherlock diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h new file mode 100644 index 0000000000..4ca7f51444 --- /dev/null +++ b/engines/sherlock/people.h @@ -0,0 +1,57 @@ +/* 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 SHERLOCK_PEOPLE_H +#define SHERLOCK_PEOPLE_H + +#include "common/scummsys.h" +#include "sherlock/sprites.h" + +namespace Sherlock { + +#define MAX_PEOPLE 2 +#define PLAYER 0 + +// Animation sequence identifiers for characters +enum { + WALK_RIGHT = 0, WALK_DOWN = 1, WALK_LEFT = 2, WALK_UP = 3, STOP_LEFT = 4, + STOP_DOWN = 5, STOP_RIGHT = 6, STOP_UP = 7, WALK_UPRIGHT = 8, + WALK_DOWNRIGHT = 9, WALK_UPLEFT = 10, WALK_DOWNLEFT = 11, + STOP_UPRIGHT = 12, STOP_UPLEFT = 13, STOP_DOWNRIGHT = 14, + STOP_DOWNLEFT = 15, TALK_RIGHT = 6, TALK_LEFT = 4 +}; + +class SherlockEngine; + +class People { +private: + SherlockEngine *_vm; + Sprite _data[MAX_PEOPLE]; +public: + People(SherlockEngine *vm); + + void reset(); +}; + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index 6636ca5be8..cdea7bd296 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -22,6 +22,8 @@ #include "sherlock/resources.h" #include "sherlock/decompress.h" +#include "sherlock/screen.h" +#include "sherlock/sherlock.h" #include "common/debug.h" namespace Sherlock { @@ -241,4 +243,123 @@ int Resources::resourceIndex() const { return _resourceIndex; } +/*----------------------------------------------------------------*/ + +SherlockEngine *ImageFile::_vm; + +void ImageFile::setVm(SherlockEngine *vm) { + _vm = vm; +} + +ImageFile::ImageFile(const Common::String &name, bool skipPal) { + Common::SeekableReadStream *stream = _vm->_res->load(name); + + Common::fill(&_palette[0], &_palette[PALETTE_SIZE], 0); + load(*stream, skipPal); + + delete stream; +} + +ImageFile::ImageFile(Common::SeekableReadStream &stream, bool skipPal) { + Common::fill(&_palette[0], &_palette[PALETTE_SIZE], 0); + load(stream, skipPal); +} + +ImageFile::~ImageFile() { + for (uint idx = 0; idx < size(); ++idx) + (*this)[idx]._frame.free(); +} + +/** + * Load the data of the sprite + */ +void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette) { + loadPalette(stream); + + while (stream.pos() < stream.size()) { + ImageFrame frame; + frame._width = stream.readUint16LE() + 1; + frame._height = stream.readUint16LE() + 1; + frame._flags = stream.readByte(); + frame._position.x = stream.readUint16LE(); + frame._position.y = stream.readByte(); + + frame._rleEncoded = !skipPalette && (frame._position.x == 1); + + if (frame._flags & 0xFF) { + // Nibble packed frame data + frame._size = (frame._width * frame._height) / 2; + } else if (frame._rleEncoded) { + // this size includes the header size, which we subtract + frame._size = stream.readUint16LE() - 11; + frame._rleMarker = stream.readByte(); + } else { + // Uncompressed data + frame._size = frame._width * frame._height; + } + + // Load data for frame and decompress it + byte *data = new byte[frame._size]; + stream.read(data, frame._size); + decompressFrame(frame, data); + delete data; + + push_back(frame); + } +} + +/** + * Gets the palette at the start of the sprite file + */ +void ImageFile::loadPalette(Common::SeekableReadStream &stream) { + // Check for palette + int v1 = stream.readUint16LE() + 1; + int v2 = stream.readUint16LE() + 1; + int size = v1 * v2; + + if ((size - 12) == PALETTE_SIZE) { + // Found palette, so read it in + stream.seek(4 + 12, SEEK_CUR); + for (int idx = 0; idx < PALETTE_SIZE; ++idx) + _palette[idx] = VGA_COLOR_TRANS(stream.readByte()); + } else { + // Not a palette, so rewind to start of frame data for normal frame processing + stream.seek(-4, SEEK_CUR); + } +} + +/** + * Decompress a single frame for the sprite + */ +void ImageFile::decompressFrame(ImageFrame &frame, const byte *src) { + frame._frame.create(frame._width, frame._height, Graphics::PixelFormat::createFormatCLUT8()); + + if (frame._flags & 0xFF) { + error("TODO: ImageFile::decompressFrame() 4-bits/pixel\n"); + } else if (frame._rleEncoded) { + // RLE encoded + byte *dst = (byte *)frame._frame.getPixels(); + + int size = frame._width * frame._height; + while (size > 0) { + if (*src == frame._rleMarker) { + byte rleColor = src[1]; + byte rleCount = src[2]; + src += 3; + size -= rleCount; + while (rleCount--) + *dst++ = rleColor; + } else { + *dst++ = *src++; + --size; + } + } + assert(size == 0); + } else { + // Uncompressed frame + Common::copy(src, src + frame._width * frame._height, + (byte *)frame._frame.getPixels()); + } +} + } // End of namespace Sherlock diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h index cd6e60c325..ad9867c523 100644 --- a/engines/sherlock/resources.h +++ b/engines/sherlock/resources.h @@ -27,8 +27,10 @@ #include "common/file.h" #include "common/hashmap.h" #include "common/hash-str.h" +#include "common/rect.h" #include "common/str.h" #include "common/stream.h" +#include "graphics/surface.h" namespace Sherlock { @@ -83,6 +85,33 @@ public: int resourceIndex() const; }; +struct ImageFrame { + uint32 _size; + uint16 _width, _height; + int _flags; + bool _rleEncoded; + Common::Point _position; + byte _rleMarker; + Graphics::Surface _frame; + + operator Graphics::Surface &() { return _frame; } +}; + +class ImageFile : public Common::Array { +private: + static SherlockEngine *_vm; + + void load(Common::SeekableReadStream &stream, bool skipPalette); + void loadPalette(Common::SeekableReadStream &stream); + void decompressFrame(ImageFrame &frame, const byte *src); +public: + byte _palette[256 * 3]; +public: + ImageFile(const Common::String &name, bool skipPal = false); + ImageFile(Common::SeekableReadStream &stream, bool skipPal = false); + ~ImageFile(); + static void setVm(SherlockEngine *vm); +}; } // End of namespace Sherlock diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index d5f63b9c0d..ca04153594 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -83,18 +83,18 @@ bool ScalpelEngine::showCityCutscene() { bool finished = _animation->playPrologue("26open1", 1, 255, true, 2); if (finished) { - Sprite titleSprites("title2.vgs", true); + ImageFile titleImages("title2.vgs", true); _screen->_backBuffer.blitFrom(*_screen); _screen->_backBuffer2.blitFrom(*_screen); // London, England - _screen->_backBuffer.transBlitFrom(titleSprites[0], Common::Point(10, 11)); + _screen->_backBuffer.transBlitFrom(titleImages[0], Common::Point(10, 11)); _screen->randomTransition(); finished = _events->delay(1000, true); // November, 1888 if (finished) { - _screen->_backBuffer.transBlitFrom(titleSprites[1], Common::Point(101, 102)); + _screen->_backBuffer.transBlitFrom(titleImages[1], Common::Point(101, 102)); _screen->randomTransition(); finished = _events->delay(5000, true); } @@ -108,16 +108,16 @@ bool ScalpelEngine::showCityCutscene() { finished = _animation->playPrologue("26open2", 1, 0, false, 2); if (finished) { - Sprite titleSprites("title.vgs", true); + ImageFile titleImages("title.vgs", true); _screen->_backBuffer.blitFrom(*_screen); _screen->_backBuffer2.blitFrom(*_screen); // The Lost Files of - _screen->_backBuffer.transBlitFrom(titleSprites[0], Common::Point(75, 6)); + _screen->_backBuffer.transBlitFrom(titleImages[0], Common::Point(75, 6)); // Sherlock Holmes - _screen->_backBuffer.transBlitFrom(titleSprites[1], Common::Point(34, 21)); + _screen->_backBuffer.transBlitFrom(titleImages[1], Common::Point(34, 21)); // copyright - _screen->_backBuffer.transBlitFrom(titleSprites[2], Common::Point(4, 190)); + _screen->_backBuffer.transBlitFrom(titleImages[2], Common::Point(4, 190)); _screen->verticalTransition(); finished = _events->delay(4000, true); @@ -135,7 +135,7 @@ bool ScalpelEngine::showCityCutscene() { if (finished) { // In the alley... - _screen->transBlitFrom(titleSprites[3], Common::Point(72, 51)); + _screen->transBlitFrom(titleImages[3], Common::Point(72, 51)); _screen->fadeIn(palette, 3); finished = _events->delay(3000, true); } diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index de351a5561..84ef44d7e1 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -30,12 +30,27 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { _goToRoom = -1; _oldCharPoint = 0; _numExits = 0; + _windowOpen = _infoFlag = false; + _menuMode = _keyboardInput = 0; - _controlSprites = new Sprite("menu.all"); + _controls = nullptr; // new ImageFile("menu.all"); } Scene::~Scene() { - delete _controlSprites; + delete _controls; +} + +void Scene::selectScene() { + // Reset fields + _numExits = 0; + _windowOpen = _infoFlag = false; + _menuMode = _keyboardInput = 0; + _oldKey = _help = _oldHelp = 0; + _oldTemp = _temp = 0; + + // Set up player + + } } // End of namespace Sherlock diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 031245b122..f92dfccfad 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -24,7 +24,7 @@ #define SHERLOCK_SCENE_H #include "common/scummsys.h" -#include "sherlock/sprite.h" +#include "sherlock/resources.h" namespace Sherlock { @@ -35,6 +35,8 @@ class SherlockEngine; class Scene { private: SherlockEngine *_vm; + + void loadScene(); public: bool _stats[SCENES_COUNT][9]; bool _savedStats[SCENES_COUNT][9]; @@ -42,12 +44,17 @@ public: Common::Point _bigPos; Common::Point _overPos; int _oldCharPoint; - Sprite *_controlSprites; + ImageFile *_controls; int _numExits; + bool _windowOpen, _infoFlag; + int _menuMode, _keyboardInput; + int _oldKey, _help, _oldHelp; + int _oldTemp, _temp; public: Scene(SherlockEngine *vm); - ~Scene(); + + void selectScene(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 8b597df31b..a292ee675c 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -74,6 +74,7 @@ void SherlockEngine::initialize() { _midi->setNativeMT32(native_mt32); */ + ImageFile::setVm(this); _res = new Resources(); _animation = new Animation(this); _debugger = new Debugger(this); @@ -83,7 +84,6 @@ void SherlockEngine::initialize() { _screen = new Screen(this); _sound = new Sound(this); _talk = new Talk(); - Sprite::setVm(this); } Common::Error SherlockEngine::run() { @@ -97,6 +97,9 @@ Common::Error SherlockEngine::run() { if (shouldQuit()) break; + // Initialize the scene + _scene->selectScene(); + // TODO: Implement game and remove this dummy loop while (!shouldQuit()) _events->pollEventsAndWait(); diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index c6023684b4..210e24c320 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -35,6 +35,7 @@ #include "sherlock/debugger.h" #include "sherlock/events.h" #include "sherlock/journal.h" +#include "sherlock/people.h" #include "sherlock/resources.h" #include "sherlock/scene.h" #include "sherlock/screen.h" @@ -77,6 +78,7 @@ public: Debugger *_debugger; EventsManager *_events; Journal *_journal; + People *_people; Resources *_res; Scene *_scene; Screen *_screen; diff --git a/engines/sherlock/sprite.cpp b/engines/sherlock/sprite.cpp deleted file mode 100644 index 8a7bb4cf29..0000000000 --- a/engines/sherlock/sprite.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "sherlock/sprite.h" -#include "sherlock/screen.h" -#include "sherlock/sherlock.h" -#include "common/debug.h" - -namespace Sherlock { - -SherlockEngine *Sprite::_vm; - -void Sprite::setVm(SherlockEngine *vm) { - _vm = vm; -} - -Sprite::Sprite(const Common::String &name, bool skipPal) { - Common::SeekableReadStream *stream = _vm->_res->load(name); - - Common::fill(&_palette[0], &_palette[PALETTE_SIZE], 0); - load(*stream, skipPal); - - delete stream; -} - -Sprite::Sprite(Common::SeekableReadStream &stream, bool skipPal) { - Common::fill(&_palette[0], &_palette[PALETTE_SIZE], 0); - load(stream, skipPal); -} - -Sprite::~Sprite() { - for (uint idx = 0; idx < size(); ++idx) - (*this)[idx]._frame.free(); -} - -/** - * Load the data of the sprite - */ -void Sprite::load(Common::SeekableReadStream &stream, bool skipPalette) { - loadPalette(stream); - - while (stream.pos() < stream.size()) { - SpriteFrame frame; - frame._width = stream.readUint16LE() + 1; - frame._height = stream.readUint16LE() + 1; - frame._flags = stream.readByte(); - frame._position.x = stream.readUint16LE(); - frame._position.y = stream.readByte(); - - frame._rleEncoded = !skipPalette && (frame._position.x == 1); - - if (frame._flags & 0xFF) { - // Nibble packed frame data - frame._size = (frame._width * frame._height) / 2; - } else if (frame._rleEncoded) { - // this size includes the header size, which we subtract - frame._size = stream.readUint16LE() - 11; - frame._rleMarker = stream.readByte(); - } else { - // Uncompressed data - frame._size = frame._width * frame._height; - } - - // Load data for frame and decompress it - byte *data = new byte[frame._size]; - stream.read(data, frame._size); - decompressFrame(frame, data); - delete data; - - push_back(frame); - } -} - -/** - * Gets the palette at the start of the sprite file - */ -void Sprite::loadPalette(Common::SeekableReadStream &stream) { - // Check for palette - int v1 = stream.readUint16LE() + 1; - int v2 = stream.readUint16LE() + 1; - int size = v1 * v2; - - if ((size - 12) == PALETTE_SIZE) { - // Found palette, so read it in - stream.seek(4 + 12, SEEK_CUR); - for (int idx = 0; idx < PALETTE_SIZE; ++idx) - _palette[idx] = VGA_COLOR_TRANS(stream.readByte()); - } else { - // Not a palette, so rewind to start of frame data for normal frame processing - stream.seek(-4, SEEK_CUR); - } -} - -/** - * Decompress a single frame for the sprite - */ -void Sprite::decompressFrame(SpriteFrame &frame, const byte *src) { - frame._frame.create(frame._width, frame._height, Graphics::PixelFormat::createFormatCLUT8()); - - if (frame._flags & 0xFF) { - debug("TODO: Sprite::decompressFrame() 4-bits/pixel\n"); - } else if (frame._rleEncoded) { - // RLE encoded - byte *dst = (byte *)frame._frame.getPixels(); - - int size = frame._width * frame._height; - while (size > 0) { - if (*src == frame._rleMarker) { - byte rleColor = src[1]; - byte rleCount = src[2]; - src += 3; - size -= rleCount; - while (rleCount--) - *dst++ = rleColor; - } else { - *dst++ = *src++; - --size; - } - } - assert(size == 0); - } else { - // Uncompressed frame - Common::copy(src, src + frame._width * frame._height, - (byte *)frame._frame.getPixels()); - } -} - -} // End of namespace Sherlock diff --git a/engines/sherlock/sprite.h b/engines/sherlock/sprite.h deleted file mode 100644 index 844013db43..0000000000 --- a/engines/sherlock/sprite.h +++ /dev/null @@ -1,65 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef SHERLOCK_SPRITE_H -#define SHERLOCK_SPRITE_H - -#include "common/array.h" -#include "common/rect.h" -#include "common/stream.h" -#include "graphics/surface.h" - -namespace Sherlock { - -class SherlockEngine; - -struct SpriteFrame { - uint32 _size; - uint16 _width, _height; - int _flags; - bool _rleEncoded; - Common::Point _position; - byte _rleMarker; - Graphics::Surface _frame; - - operator Graphics::Surface &() { return _frame; } -}; - -class Sprite: public Common::Array { -private: - static SherlockEngine *_vm; - - void load(Common::SeekableReadStream &stream, bool skipPalette); - void loadPalette(Common::SeekableReadStream &stream); - void decompressFrame(SpriteFrame &frame, const byte *src); -public: - byte _palette[256 * 3]; -public: - Sprite(const Common::String &name, bool skipPal = false); - Sprite(Common::SeekableReadStream &stream, bool skipPal = false); - ~Sprite(); - static void setVm(SherlockEngine *vm); -}; - -} // End of namespace Sherlock - -#endif diff --git a/engines/sherlock/sprites.cpp b/engines/sherlock/sprites.cpp new file mode 100644 index 0000000000..6e33219309 --- /dev/null +++ b/engines/sherlock/sprites.cpp @@ -0,0 +1,27 @@ +/* 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 "sherlock/sprites.h" + +namespace Sherlock { + +} // End of namespace Sherlock diff --git a/engines/sherlock/sprites.h b/engines/sherlock/sprites.h new file mode 100644 index 0000000000..631693d815 --- /dev/null +++ b/engines/sherlock/sprites.h @@ -0,0 +1,83 @@ +/* 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 SHERLOCK_SPRITES_H +#define SHERLOCK_SPRITES_H + +#include "common/scummsys.h" +#include "common/rect.h" +#include "common/str-array.h" +#include "common/str.h" +#include "sherlock/resources.h" + +namespace Sherlock { + +class SherlockEngine; + +enum ObjectAllow { + ALLOW_MOVEMENT = 1, ALLOW_OPEN = 2, ALLOW_CLOSE = 4 +}; + +enum SpriteType { + INVALID = 0, + CHARACTER = 1, + CURSOR = 2, + STATIC_BG_SHAPE = 3, // Background shape that doesn't animate + ACTIVE_BG_SHAPE = 4, // Background shape that animates + REMOVE = 5, // Object should be removed next frame + NO_SHAPE = 6, // Background object with no shape + HIDDEN = 7, // Hidden backgruond object + HIDE_SHAPE = 8 // Object needs to be hidden +}; + +#define MAX_HOLMES_SEQUENCE 16 +#define MAX_FRAME 30 + +struct Sprite { + Common::String _name; // Name + Common::String _description; // Description + Common::StringArray _examine; // Examine in-depth description + Common::String _pickUp; // Message for if you can't pick up object + + const uint8 (*_sequences)[MAX_HOLMES_SEQUENCE][MAX_FRAME]; // Holds animation sequences + Sprite *_sprites; // Sprite shapes + ImageFrame *_spriteFrame; // Pointer to shape in the sprite + int _walkCount; // Character walk counter + int _allow; // Allowed menu commands - ObjectAllow + int _frameNumber; // Frame number in rame sequence to draw + int _sequenceNumber; // Sequence being used + Common::Point _position; // Current position + Common::Point _movement; // Momvement amount + Common::Point _oldPosition; // Old position + Common::Point _oldSize; // Image's old size + Common::Point _goto; // Walk destination + SpriteType _type; // Type of object + int _pickup; + Common::Point _noShapeSize; // Size of a NO_SHAPE + int _status; // Status: open/closed, moved/not moved + byte _misc; // Miscellaneous use + int _numFrames; // How many frames the object has +}; + +} // End of namespace Sherlock + +#endif -- cgit v1.2.3 From 77a4227aa4915a860accdd761fb9695d390641dd Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 19 Mar 2015 23:31:28 -0400 Subject: SHERLOCK: Added loading of scene objects --- engines/sherlock/module.mk | 2 +- engines/sherlock/objects.cpp | 155 ++++++++++++++++++++++++++++++++++++++ engines/sherlock/objects.h | 166 +++++++++++++++++++++++++++++++++++++++++ engines/sherlock/people.cpp | 2 +- engines/sherlock/people.h | 2 +- engines/sherlock/resources.cpp | 7 ++ engines/sherlock/resources.h | 2 + engines/sherlock/scene.cpp | 127 ++++++++++++++++++++++++++++++- engines/sherlock/scene.h | 35 +++++++++ engines/sherlock/sherlock.cpp | 11 ++- engines/sherlock/sprites.cpp | 27 ------- engines/sherlock/sprites.h | 83 --------------------- 12 files changed, 503 insertions(+), 116 deletions(-) create mode 100644 engines/sherlock/objects.cpp create mode 100644 engines/sherlock/objects.h delete mode 100644 engines/sherlock/sprites.cpp delete mode 100644 engines/sherlock/sprites.h diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk index 865b422ef9..dc88ab3f5f 100644 --- a/engines/sherlock/module.mk +++ b/engines/sherlock/module.mk @@ -12,13 +12,13 @@ MODULE_OBJS = \ events.o \ graphics.o \ journal.o \ + objects.o \ people.o \ resources.o \ scene.o \ screen.o \ sherlock.o \ sound.o \ - sprites.o \ talk.o # This module can be built as a plugin diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp new file mode 100644 index 0000000000..2386c00686 --- /dev/null +++ b/engines/sherlock/objects.cpp @@ -0,0 +1,155 @@ +/* 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 "sherlock/objects.h" + +namespace Sherlock { + +/** + * Reset the data for the sprite + */ +void Sprite::clear() { + _name = ""; + _description = ""; + _examine.clear(); + _pickUp = ""; + _sequences = nullptr; + _images = nullptr; + _imageFrame = nullptr; + _walkCount = 0; + _allow = 0; + _frameNumber = _sequenceNumber = 0; + _position.x = _position.y = 0; + _movement.x = _movement.y = 0; + _oldPosition.x = _oldPosition.y = 0; + _oldSize.x = _oldSize.y = 0; + _goto.x = _goto.y = 0; + _type = INVALID; + _pickUp.clear(); + _noShapeSize.x = _noShapeSize.y = 0; + _status = 0; + _misc = 0; + _numFrames = 0; +} + +/*----------------------------------------------------------------*/ + +void ActionType::synchronize(Common::SeekableReadStream &s) { + char buffer[12]; + + _cAnimNum = s.readByte(); + _cAnimSpeed = s.readByte(); + + for (int idx = 0; idx < 4; ++idx) { + s.read(buffer, 12); + _names[idx] = Common::String(buffer); + } +} + +/*----------------------------------------------------------------*/ + +void UseType::synchronize(Common::SeekableReadStream &s) { + char buffer[12]; + + _cAnimNum = s.readByte(); + _cAnimSpeed = s.readByte(); + + for (int idx = 0; idx < 4; ++idx) { + s.read(buffer, 12); + _names[idx] = Common::String(buffer); + } + + _useFlag = s.readUint16LE(); + _dFlag[0] = s.readUint16LE(); + _lFlag[0] = s.readUint16LE(); + _lFlag[1] = s.readUint16LE(); + + s.read(buffer, 12); + _target = Common::String(buffer); +} + +/*----------------------------------------------------------------*/ + +void Object::synchronize(Common::SeekableReadStream &s) { + char buffer[50]; + + s.read(buffer, 12); + _name = Common::String(buffer); + s.read(buffer, 41); + _description = Common::String(buffer); + + _examine.clear(); + _sequences = nullptr; + _images = nullptr; + _imageFrame = nullptr; + s.seek(16, SEEK_CUR); + + _walkCount = s.readByte(); + _allow = s.readByte(); + _frameNumber = s.readSint16LE(); + _sequenceNumber = s.readSint16LE(); + _position.x = s.readSint16LE(); + _position.y = s.readSint16LE(); + _movement.x = s.readSint16LE(); + _movement.y = s.readSint16LE(); + _type = (SpriteType)s.readUint16LE(); + _oldPosition.x = s.readSint16LE(); + _oldPosition.y = s.readSint16LE(); + _oldSize.x = s.readUint16LE(); + _oldSize.y = s.readUint16LE(); + _goto.x = s.readSint16LE(); + _goto.y = s.readSint16LE(); + + _pickup = s.readByte(); + _defaultCommand = s.readByte(); + _lookFlag = s.readUint16LE(); + _pickupFlag = s.readUint16LE(); + _requiredFlag = s.readUint16LE(); + _noShapeSize.x = s.readUint16LE(); + _noShapeSize.y = s.readUint16LE(); + _status = s.readUint16LE(); + _misc = s.readByte(); + _maxFrames = s.readUint16LE(); + _flags = s.readByte(); + _aOpen.synchronize(s); + _aType = s.readByte(); + _lookFrames = s.readByte(); + _seqcounter = s.readByte(); + _lookPosition.x = s.readUint16LE(); + _lookPosition.y = s.readByte(); + _lookFacing = s.readByte(); + _lookcAnim = s.readByte(); + _aClose.synchronize(s); + _seqStack = s.readByte(); + _seqTo = s.readByte(); + _descOfs = s.readUint16LE(); + _seqcounter2 = s.readByte(); + _seqSize = s.readUint16LE(); + s.skip(1); + _aMove.synchronize(s); + s.skip(8); + + for (int idx = 0; idx < 4; ++idx) + _use[idx].synchronize(s); +} + +} // End of namespace Sherlock diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h new file mode 100644 index 0000000000..f730240479 --- /dev/null +++ b/engines/sherlock/objects.h @@ -0,0 +1,166 @@ +/* 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 SHERLOCK_OBJECTS_H +#define SHERLOCK_OBJECTS_H + +#include "common/scummsys.h" +#include "common/rect.h" +#include "common/str-array.h" +#include "common/str.h" +#include "sherlock/resources.h" + +namespace Sherlock { + +class SherlockEngine; + +enum ObjectAllow { + ALLOW_MOVEMENT = 1, ALLOW_OPEN = 2, ALLOW_CLOSE = 4 +}; + +enum SpriteType { + INVALID = 0, + CHARACTER = 1, + CURSOR = 2, + STATIC_BG_SHAPE = 3, // Background shape that doesn't animate + ACTIVE_BG_SHAPE = 4, // Background shape that animates + REMOVE = 5, // Object should be removed next frame + NO_SHAPE = 6, // Background object with no shape + HIDDEN = 7, // Hidden backgruond object + HIDE_SHAPE = 8 // Object needs to be hidden +}; + +#define MAX_HOLMES_SEQUENCE 16 +#define MAX_FRAME 30 + +struct Sprite { + Common::String _name; // Name + Common::String _description; // Description + Common::StringArray _examine; // Examine in-depth description + Common::String _pickUp; // Message for if you can't pick up object + + const uint8 (*_sequences)[MAX_HOLMES_SEQUENCE][MAX_FRAME]; // Holds animation sequences + ImageFile *_images; // Sprite images + ImageFrame *_imageFrame; // Pointer to shape in the images + int _walkCount; // Character walk counter + int _allow; // Allowed menu commands - ObjectAllow + int _frameNumber; // Frame number in rame sequence to draw + int _sequenceNumber; // Sequence being used + Common::Point _position; // Current position + Common::Point _movement; // Momvement amount + Common::Point _oldPosition; // Old position + Common::Point _oldSize; // Image's old size + Common::Point _goto; // Walk destination + SpriteType _type; // Type of object + int _pickup; + Common::Point _noShapeSize; // Size of a NO_SHAPE + int _status; // Status: open/closed, moved/not moved + int8 _misc; // Miscellaneous use + int _numFrames; // How many frames the object has + + Sprite() { clear(); } + void clear(); +}; + +struct ActionType { + char _cAnimNum; + char _cAnimSpeed; // if high bit set, play in reverse + Common::String _names[4]; + + void synchronize(Common::SeekableReadStream &s); +}; + +struct UseType { + int _cAnimNum; + int _cAnimSpeed; // if high bit set, play in reverse + Common::String _names[4]; + int _useFlag; // Which flag USE will set (if any) + int _dFlag[1]; + int _lFlag[2]; + Common::String _target; + + void synchronize(Common::SeekableReadStream &s); +}; + +struct Object { + Common::String _name; // Name + Common::String _description; // Description + Common::StringArray _examine; // Examine in-depth description + uint8 (*_sequences)[MAX_HOLMES_SEQUENCE][MAX_FRAME]; // Holds animation sequences + ImageFile *_images; // Sprite images + ImageFrame *_imageFrame; // Pointer to shape in the images + int _walkCount; // Character walk counter + int _allow; // Allowed menu commands - ObjectAllow + int _frameNumber; // Frame number in rame sequence to draw + int _sequenceNumber; // Sequence being used + SpriteType _type; // Object type + Common::Point _position; // Current position + Common::Point _movement; // Momvement amount + Common::Point _oldPosition; // Old position + Common::Point _oldSize; // Image's old size + Common::Point _goto; // Walk destination + + int _pickup; + int _defaultCommand; // Default right-click command + int _lookFlag; // Which flag LOOK will set (if any) + int _pickupFlag; // Which flag PICKUP will set (if any) + int _requiredFlag; // Object will be hidden if not set + Common::Point _noShapeSize; // Size of a NO_SHAPE + int _status; // Status (open/closed, moved/not) + int8 _misc; // Misc field -- use varies with type + int _maxFrames; // Number of frames + int _flags; // Tells if object can be walked behind + ActionType _aOpen; // Holds data for moving object + int _aType; // Tells if this is an object, person, talk, etc. + int _lookFrames; // How many frames to play of the look anim before pausing + int _seqcounter; // How many times this sequence has been executed + Common::Point _lookPosition; // Where to walk when examining object + int _lookFacing; // Direction to face when examining object + int _lookcAnim; + ActionType _aClose; + int _seqStack; // Allows gosubs to return to calling frame + int _seqTo; // Allows 1-5, 8-3 type sequences encoded in 2 bytes + uint _descOfs; // Tells where description starts in DescText + int _seqcounter2; // Counter of calling frame sequence + uint _seqSize; // Tells where description starts + ActionType _aMove; + UseType _use[4]; + + void synchronize(Common::SeekableReadStream &s); +}; + +struct CAnim { + Common::String _name; // Name + int _sequences[MAX_FRAME]; // Animation sequences + Common::Point _position; // Position + int _size; // Size of uncompressed animation + SpriteType _type; + int _flags; // Tells if can be walked behind + Common::Point _goto; // coords holmes should walk to before starting canim + int _sequenceNumber; + Common::Point _teleportPos; // Location Holmes shoul teleport to after + int _teleportS; // playing canim +}; + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 53ccaf5baf..cdb498e5e6 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -56,7 +56,7 @@ void People::reset() { p._position = Common::Point(10000, 11000); p._sequenceNumber = STOP_DOWNRIGHT; p._sequences = &CHARACTER_SEQUENCES; - p._spriteFrame = nullptr; + p._imageFrame = nullptr; p._frameNumber = 1; p._movement = Common::Point(0, 0); p._oldPosition = Common::Point(0, 0); diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index 4ca7f51444..3f639a6d44 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -24,7 +24,7 @@ #define SHERLOCK_PEOPLE_H #include "common/scummsys.h" -#include "sherlock/sprites.h" +#include "sherlock/objects.h" namespace Sherlock { diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index cdea7bd296..66feca6bd5 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -194,6 +194,13 @@ Common::SeekableReadStream *Resources::load(const Common::String &filename, cons return stream; } +/** + * Returns true if the given file exists on disk or in the cache + */ +bool Resources::exists(const Common::String &filename) const { + Common::File f; + return f.exists(filename) || _cache.isCached(filename); +} /** * Reads in the index from a library file, and caches it's index for later use diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h index ad9867c523..2f9222c1fd 100644 --- a/engines/sherlock/resources.h +++ b/engines/sherlock/resources.h @@ -82,6 +82,8 @@ public: Common::SeekableReadStream *load(const Common::String &filename, const Common::String &libraryFile); + bool exists(const Common::String &filename) const; + int resourceIndex() const; }; diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 84ef44d7e1..267b02b43c 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -21,9 +21,37 @@ */ #include "sherlock/scene.h" +#include "sherlock/sherlock.h" +#include "sherlock/decompress.h" namespace Sherlock { +void BgFileHeader::synchronize(Common::SeekableReadStream &s) { + _numStructs = s.readUint16LE(); + _numImages = s.readUint16LE(); + _numcAnimations = s.readUint16LE(); + _descSize = s.readUint16LE(); + _seqSize = s.readUint16LE(); + _fill = s.readUint16LE(); +} + +/*----------------------------------------------------------------*/ + +void BgfileheaderInfo::synchronize(Common::SeekableReadStream &s) { + _fSize = s.readUint32LE(); + _maxFrames = s.readByte(); + + char buffer[9]; + s.read(buffer, 9); + _filename = Common::String(buffer); +} + +int _fSize; // How long images are +int _maxFrames; // How many unique frames in object +Common::String _filename; // Filename of object + +/*----------------------------------------------------------------*/ + Scene::Scene(SherlockEngine *vm): _vm(vm) { for (int idx = 0; idx < SCENES_COUNT; ++idx) Common::fill(&_stats[idx][0], &_stats[idx][9], false); @@ -32,6 +60,11 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { _numExits = 0; _windowOpen = _infoFlag = false; _menuMode = _keyboardInput = 0; + _walkedInScene = false; + _ongoingCans = 0; + _version = 0; + _lzwMode = false; + _invGraphicItems = 0; _controls = nullptr; // new ImageFile("menu.all"); } @@ -48,9 +81,101 @@ void Scene::selectScene() { _oldKey = _help = _oldHelp = 0; _oldTemp = _temp = 0; - // Set up player + // Load the scene + Common::String sceneFile = Common::String::format("res%02d", _goToRoom); + Common::String roomName = Common::String::format("res%02d.rrm", _goToRoom); + _goToRoom = -1; + + loadScene(sceneFile); +} + +/** + * Loads the data associated for a given scene. The .BGD file's format is: + * BGHEADER: Holds an index for the rest of the file + * STRUCTS: The objects for the scene + * IMAGES: The graphic information for the structures + * + * The _misc field of the structures contains the number of the graphic image + * that it should point to after loading; _misc is then set to 0. + */ +void Scene::loadScene(const Common::String &filename) { + bool flag; + + _walkedInScene = false; + _ongoingCans = 0; + + // Reset the list of walkable areas + _roomBounds.clear(); + _roomBounds.push_back(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + + _descText.clear(); + _comments = ""; + _bgShapes.clear(); + _cAnim.clear(); + _sequenceBuffer.clear(); + + // + // Load background shapes from .rrm + // + + Common::String rrmFile = filename + ".rrm"; + flag = _vm->_res->exists(rrmFile); + if (flag) { + Common::SeekableReadStream *rrmStream = _vm->_res->load(rrmFile); + + rrmStream->seek(39); + _version = rrmStream->readByte(); + _lzwMode = _version == 10; + + // Go to header and read it in + rrmStream->seek(rrmStream->readUint32LE()); + BgFileHeader bgHeader; + bgHeader.synchronize(*rrmStream); + + _cAnim.resize(bgHeader._numcAnimations); + _invGraphicItems = bgHeader._numImages + 1; + + // Read in the shapes header info + Common::Array bgInfo; + bgInfo.resize(bgHeader._numStructs); + + for (uint idx = 0; idx < bgInfo.size(); ++idx) + bgInfo[idx].synchronize(*rrmStream); + + // Initialize the cAnim + for (uint idx = 0; idx < _cAnim.size(); ++idx) { + _cAnim[idx]._position.x = -1; + _cAnim[idx]._goto.x = -1; + _cAnim[idx]._teleportPos.x = -1; + } + + // Read information + Common::SeekableReadStream *infoStream = !_lzwMode ? rrmStream : + decompressLZ(*rrmStream, bgHeader._numImages * 569 + + bgHeader._descSize + bgHeader._seqSize); + + _bgShapes.resize(bgHeader._numStructs); + for (uint idx = 0; idx < _bgShapes.size(); ++idx) + _bgShapes[idx].synchronize(*infoStream); + + if (bgHeader._descSize) { + _descText.resize(bgHeader._descSize); + infoStream->read(&_descText[0], bgHeader._descSize); + } + + if (bgHeader._seqSize) { + _sequenceBuffer.resize(bgHeader._seqSize); + infoStream->read(&_sequenceBuffer[0], bgHeader._seqSize); + } + + if (_lzwMode) + delete infoStream; + // Load shapes + // TODO + delete rrmStream; + } } } // End of namespace Sherlock diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index f92dfccfad..e216c2bd9d 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -24,6 +24,9 @@ #define SHERLOCK_SCENE_H #include "common/scummsys.h" +#include "common/array.h" +#include "common/rect.h" +#include "sherlock/objects.h" #include "sherlock/resources.h" namespace Sherlock { @@ -32,11 +35,32 @@ namespace Sherlock { class SherlockEngine; +struct BgFileHeader { + int _numStructs; + int _numImages; + int _numcAnimations; + int _descSize; + int _seqSize; + int _fill; + + void synchronize(Common::SeekableReadStream &s); +}; + +struct BgfileheaderInfo { + int _fSize; // How long images are + int _maxFrames; // How many unique frames in object + Common::String _filename; // Filename of object + + void synchronize(Common::SeekableReadStream &s); +}; + class Scene { private: SherlockEngine *_vm; void loadScene(); + + void loadScene(const Common::String &filename); public: bool _stats[SCENES_COUNT][9]; bool _savedStats[SCENES_COUNT][9]; @@ -50,6 +74,17 @@ public: int _menuMode, _keyboardInput; int _oldKey, _help, _oldHelp; int _oldTemp, _temp; + bool _walkedInScene; + int _ongoingCans; + int _version; + bool _lzwMode; + int _invGraphicItems; + Common::String _comments; + Common::Array _descText; + Common::Array _roomBounds; + Common::Array _bgShapes; + Common::Array _cAnim; + Common::Array _sequenceBuffer; public: Scene(SherlockEngine *vm); ~Scene(); diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index a292ee675c..a963d0bfe5 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -34,6 +34,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _debugger = nullptr; _events = nullptr; _journal = nullptr; + _people = nullptr; _res = nullptr; _scene = nullptr; _screen = nullptr; @@ -49,6 +50,7 @@ SherlockEngine::~SherlockEngine() { delete _debugger; delete _events; delete _journal; + delete _people; delete _res; delete _scene; delete _screen; @@ -80,6 +82,7 @@ void SherlockEngine::initialize() { _debugger = new Debugger(this); _events = new EventsManager(this); _journal = new Journal(); + _people = new People(this); _scene = new Scene(this); _screen = new Screen(this); _sound = new Sound(this); @@ -92,12 +95,16 @@ Common::Error SherlockEngine::run() { showOpening(); while (!shouldQuit()) { - // Prepare for scene, and handle any game-specific scenes + // Prepare for scene, and handle any game-specific scenes. This allows + // for game specific cutscenes or mini-games that aren't standard scenes startScene(); if (shouldQuit()) break; - // Initialize the scene + // Reset the active characters to initially just Sherlock + _people->reset(); + + // Initialize and load the scene. _scene->selectScene(); // TODO: Implement game and remove this dummy loop diff --git a/engines/sherlock/sprites.cpp b/engines/sherlock/sprites.cpp deleted file mode 100644 index 6e33219309..0000000000 --- a/engines/sherlock/sprites.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "sherlock/sprites.h" - -namespace Sherlock { - -} // End of namespace Sherlock diff --git a/engines/sherlock/sprites.h b/engines/sherlock/sprites.h deleted file mode 100644 index 631693d815..0000000000 --- a/engines/sherlock/sprites.h +++ /dev/null @@ -1,83 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef SHERLOCK_SPRITES_H -#define SHERLOCK_SPRITES_H - -#include "common/scummsys.h" -#include "common/rect.h" -#include "common/str-array.h" -#include "common/str.h" -#include "sherlock/resources.h" - -namespace Sherlock { - -class SherlockEngine; - -enum ObjectAllow { - ALLOW_MOVEMENT = 1, ALLOW_OPEN = 2, ALLOW_CLOSE = 4 -}; - -enum SpriteType { - INVALID = 0, - CHARACTER = 1, - CURSOR = 2, - STATIC_BG_SHAPE = 3, // Background shape that doesn't animate - ACTIVE_BG_SHAPE = 4, // Background shape that animates - REMOVE = 5, // Object should be removed next frame - NO_SHAPE = 6, // Background object with no shape - HIDDEN = 7, // Hidden backgruond object - HIDE_SHAPE = 8 // Object needs to be hidden -}; - -#define MAX_HOLMES_SEQUENCE 16 -#define MAX_FRAME 30 - -struct Sprite { - Common::String _name; // Name - Common::String _description; // Description - Common::StringArray _examine; // Examine in-depth description - Common::String _pickUp; // Message for if you can't pick up object - - const uint8 (*_sequences)[MAX_HOLMES_SEQUENCE][MAX_FRAME]; // Holds animation sequences - Sprite *_sprites; // Sprite shapes - ImageFrame *_spriteFrame; // Pointer to shape in the sprite - int _walkCount; // Character walk counter - int _allow; // Allowed menu commands - ObjectAllow - int _frameNumber; // Frame number in rame sequence to draw - int _sequenceNumber; // Sequence being used - Common::Point _position; // Current position - Common::Point _movement; // Momvement amount - Common::Point _oldPosition; // Old position - Common::Point _oldSize; // Image's old size - Common::Point _goto; // Walk destination - SpriteType _type; // Type of object - int _pickup; - Common::Point _noShapeSize; // Size of a NO_SHAPE - int _status; // Status: open/closed, moved/not moved - byte _misc; // Miscellaneous use - int _numFrames; // How many frames the object has -}; - -} // End of namespace Sherlock - -#endif -- cgit v1.2.3 From 43381e98197f8adb5ee73f8dc05c81b972fedeae Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 20 Mar 2015 07:54:39 -0400 Subject: SHERLOCK: Further scene loading code --- engines/sherlock/objects.cpp | 38 ++++++++++++++++-- engines/sherlock/objects.h | 19 +++++++-- engines/sherlock/scene.cpp | 95 ++++++++++++++++++++++++++++++++++++++------ engines/sherlock/scene.h | 5 ++- 4 files changed, 136 insertions(+), 21 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 2386c00686..73e6397b50 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -101,7 +101,10 @@ void Object::synchronize(Common::SeekableReadStream &s) { _sequences = nullptr; _images = nullptr; _imageFrame = nullptr; - s.seek(16, SEEK_CUR); + + s.skip(4); + _sequenceOffset = s.readUint32LE(); + s.seek(8, SEEK_CUR); _walkCount = s.readByte(); _allow = s.readByte(); @@ -133,7 +136,7 @@ void Object::synchronize(Common::SeekableReadStream &s) { _aOpen.synchronize(s); _aType = s.readByte(); _lookFrames = s.readByte(); - _seqcounter = s.readByte(); + _seqCounter = s.readByte(); _lookPosition.x = s.readUint16LE(); _lookPosition.y = s.readByte(); _lookFacing = s.readByte(); @@ -141,7 +144,7 @@ void Object::synchronize(Common::SeekableReadStream &s) { _aClose.synchronize(s); _seqStack = s.readByte(); _seqTo = s.readByte(); - _descOfs = s.readUint16LE(); + _descOffset = s.readUint16LE(); _seqcounter2 = s.readByte(); _seqSize = s.readUint16LE(); s.skip(1); @@ -152,4 +155,33 @@ void Object::synchronize(Common::SeekableReadStream &s) { _use[idx].synchronize(s); } +/*----------------------------------------------------------------*/ + +void CAnim::synchronize(Common::SeekableReadStream &s) { + char buffer[12]; + s.read(buffer, 12); + _name = Common::String(buffer); + + s.read(_sequences, 30); + _position.x = s.readSint16LE(); + _position.y = s.readSint16LE(); + _size = s.readUint32LE(); + _type = (SpriteType)s.readUint16LE(); + _flags = s.readByte(); + _goto.x = s.readSint16LE(); + _goto.y = s.readSint16LE(); + _sequenceNumber = s.readSint16LE(); + _teleportPos.x = s.readSint16LE(); + _teleportPos.y = s.readSint16LE(); + _teleportS = s.readSint16LE(); +} + +/*----------------------------------------------------------------*/ + +InvGraphicType::InvGraphicType() { + _images = nullptr; + _maxFrames = 0; + _filesize = 0; +} + } // End of namespace Sherlock diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index f730240479..31d9520932 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -104,8 +104,9 @@ struct UseType { struct Object { Common::String _name; // Name Common::String _description; // Description - Common::StringArray _examine; // Examine in-depth description - uint8 (*_sequences)[MAX_HOLMES_SEQUENCE][MAX_FRAME]; // Holds animation sequences + Common::String _examine; // Examine in-depth description + int _sequenceOffset; + uint8 *_sequences; // Holds animation sequences ImageFile *_images; // Sprite images ImageFrame *_imageFrame; // Pointer to shape in the images int _walkCount; // Character walk counter @@ -132,14 +133,14 @@ struct Object { ActionType _aOpen; // Holds data for moving object int _aType; // Tells if this is an object, person, talk, etc. int _lookFrames; // How many frames to play of the look anim before pausing - int _seqcounter; // How many times this sequence has been executed + int _seqCounter; // How many times this sequence has been executed Common::Point _lookPosition; // Where to walk when examining object int _lookFacing; // Direction to face when examining object int _lookcAnim; ActionType _aClose; int _seqStack; // Allows gosubs to return to calling frame int _seqTo; // Allows 1-5, 8-3 type sequences encoded in 2 bytes - uint _descOfs; // Tells where description starts in DescText + uint _descOffset; // Tells where description starts in DescText int _seqcounter2; // Counter of calling frame sequence uint _seqSize; // Tells where description starts ActionType _aMove; @@ -159,8 +160,18 @@ struct CAnim { int _sequenceNumber; Common::Point _teleportPos; // Location Holmes shoul teleport to after int _teleportS; // playing canim + + void synchronize(Common::SeekableReadStream &s); }; +struct InvGraphicType { + ImageFile *_images; // Object images + int _maxFrames; // How many frames in object + int _filesize; // File size + + InvGraphicType(); +} ; + } // End of namespace Sherlock #endif diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 267b02b43c..ffae6f60c1 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -38,7 +38,7 @@ void BgFileHeader::synchronize(Common::SeekableReadStream &s) { /*----------------------------------------------------------------*/ void BgfileheaderInfo::synchronize(Common::SeekableReadStream &s) { - _fSize = s.readUint32LE(); + _filesize = s.readUint32LE(); _maxFrames = s.readByte(); char buffer[9]; @@ -71,6 +71,15 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { Scene::~Scene() { delete _controls; + clear(); +} + +/** + * Takes care of clearing any scene data + */ +void Scene::clear() { + for (uint idx = 0; idx < _bgShapes.size(); ++idx) + delete _bgShapes[idx]._images; } void Scene::selectScene() { @@ -108,6 +117,7 @@ void Scene::loadScene(const Common::String &filename) { _roomBounds.clear(); _roomBounds.push_back(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + clear(); _descText.clear(); _comments = ""; _bgShapes.clear(); @@ -131,8 +141,6 @@ void Scene::loadScene(const Common::String &filename) { rrmStream->seek(rrmStream->readUint32LE()); BgFileHeader bgHeader; bgHeader.synchronize(*rrmStream); - - _cAnim.resize(bgHeader._numcAnimations); _invGraphicItems = bgHeader._numImages + 1; // Read in the shapes header info @@ -142,20 +150,13 @@ void Scene::loadScene(const Common::String &filename) { for (uint idx = 0; idx < bgInfo.size(); ++idx) bgInfo[idx].synchronize(*rrmStream); - // Initialize the cAnim - for (uint idx = 0; idx < _cAnim.size(); ++idx) { - _cAnim[idx]._position.x = -1; - _cAnim[idx]._goto.x = -1; - _cAnim[idx]._teleportPos.x = -1; - } - // Read information Common::SeekableReadStream *infoStream = !_lzwMode ? rrmStream : decompressLZ(*rrmStream, bgHeader._numImages * 569 + bgHeader._descSize + bgHeader._seqSize); - _bgShapes.resize(bgHeader._numStructs); - for (uint idx = 0; idx < _bgShapes.size(); ++idx) + _bgShapes.resize(bgHeader._numStructs + 1); + for (int idx = 0; idx < bgHeader._numStructs; ++idx) _bgShapes[idx].synchronize(*infoStream); if (bgHeader._descSize) { @@ -171,11 +172,79 @@ void Scene::loadScene(const Common::String &filename) { if (_lzwMode) delete infoStream; - // Load shapes + // Set up inv list + _inv.resize(bgHeader._numImages + 1); + for (int idx = 0; idx < bgHeader._numImages; ++idx) { + _inv[idx + 1]._filesize = bgInfo[idx]._filesize; + _inv[idx + 1]._maxFrames = bgInfo[idx]._maxFrames; + + // Read in the image data + Common::SeekableReadStream *imageStream = !_lzwMode ? rrmStream : + decompressLZ(*rrmStream, bgInfo[idx]._filesize); + + _inv[idx + 1]._images = new ImageFile(*imageStream); + + if (_lzwMode) + delete imageStream; + } + + // Set up the bgShapes + for (int idx = 0; idx < bgHeader._numStructs; ++idx) { + _bgShapes[idx]._examine = Common::String(&_descText[_bgShapes[idx]._descOffset]); + _bgShapes[idx]._sequences = &_sequenceBuffer[_bgShapes[idx]._sequenceOffset]; + _bgShapes[idx]._misc = 0; + _bgShapes[idx]._seqCounter = 0; + _bgShapes[idx]._seqcounter2 = 0; + _bgShapes[idx]._seqStack = 0; + _bgShapes[idx]._frameNumber = -1; + _bgShapes[idx]._position = Common::Point(0, 0); + _bgShapes[idx]._oldSize = Common::Point(1, 1); + + _bgShapes[idx]._images = _inv[_bgShapes[idx]._misc]._images; + _bgShapes[idx]._imageFrame = !_bgShapes[idx]._images ? (ImageFrame *)nullptr : + &(*_bgShapes[idx]._images)[0]; + } + + // Set up end of list + _bgShapes[bgHeader._numStructs]._sequences = &_sequenceBuffer[0] + bgHeader._seqSize; + _bgShapes[bgHeader._numStructs]._examine = nullptr; + + // Load in cAnim list + Common::SeekableReadStream *canimStream = !_lzwMode ? rrmStream : + decompressLZ(*rrmStream, 65 * bgHeader._numcAnimations); + + _cAnim.resize(bgHeader._numcAnimations); + for (uint idx = 0; idx < _cAnim.size(); ++idx) + _cAnim[idx].synchronize(*canimStream); + + if (_lzwMode) + delete canimStream; + + // Read in the room bounding areas + int size = rrmStream->readUint16LE(); + Common::SeekableReadStream *boundsStream = !_lzwMode ? rrmStream : + decompressLZ(*rrmStream, size); + + _roomBounds.resize(size / 10); + for (uint idx = 0; idx < _roomBounds.size(); ++idx) { + _roomBounds[idx].left = boundsStream->readSint16LE(); + _roomBounds[idx].top = boundsStream->readSint16LE(); + _roomBounds[idx].setWidth(boundsStream->readSint16LE()); + _roomBounds[idx].setHeight(boundsStream->readSint16LE()); + boundsStream->skip(2); // Skip unused scene number field + } + + if (_lzwMode) + delete boundsStream; + + // Back at version byte, so skip over it + rrmStream->skip(1); + // TODO delete rrmStream; } + } } // End of namespace Sherlock diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index e216c2bd9d..2280e169b7 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -47,7 +47,7 @@ struct BgFileHeader { }; struct BgfileheaderInfo { - int _fSize; // How long images are + int _filesize; // How long images are int _maxFrames; // How many unique frames in object Common::String _filename; // Filename of object @@ -85,10 +85,13 @@ public: Common::Array _bgShapes; Common::Array _cAnim; Common::Array _sequenceBuffer; + Common::Array _inv; public: Scene(SherlockEngine *vm); ~Scene(); + void clear(); + void selectScene(); }; -- cgit v1.2.3 From cf92e540db2d58f243abe595da40a7da4450911f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 20 Mar 2015 19:44:32 -0400 Subject: SHERLOCK: More scene loading code and support methods --- engines/sherlock/objects.cpp | 37 +++++++- engines/sherlock/objects.h | 26 +++++- engines/sherlock/scene.cpp | 196 ++++++++++++++++++++++++++++++++++++++++-- engines/sherlock/scene.h | 48 ++++++++++- engines/sherlock/screen.cpp | 2 + engines/sherlock/screen.h | 3 + engines/sherlock/sherlock.cpp | 1 + engines/sherlock/sherlock.h | 2 + engines/sherlock/sound.cpp | 4 + engines/sherlock/sound.h | 1 + 10 files changed, 308 insertions(+), 12 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 73e6397b50..aa9b391f96 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -134,7 +134,7 @@ void Object::synchronize(Common::SeekableReadStream &s) { _maxFrames = s.readUint16LE(); _flags = s.readByte(); _aOpen.synchronize(s); - _aType = s.readByte(); + _aType = (AType)s.readByte(); _lookFrames = s.readByte(); _seqCounter = s.readByte(); _lookPosition.x = s.readUint16LE(); @@ -155,6 +155,41 @@ void Object::synchronize(Common::SeekableReadStream &s) { _use[idx].synchronize(s); } +void Object::toggleHidden() { + if (_type != HIDDEN && _type != HIDE_SHAPE && _type != INVALID) { + if (_seqTo != 0) + _sequences[_frameNumber] = _seqTo + SEQ_TO_CODE + 128; + _seqTo = 0; + + if (_images == nullptr || _images->size() == 0) + // No shape to erase, so flag as hidden + _type = HIDDEN; + else + // Otherwise, flag it to be hidden after it gets erased + _type = HIDE_SHAPE; + } else if (_type != INVALID) { + if (_seqTo != 0) + _sequences[_frameNumber] = _seqTo + SEQ_TO_CODE + 128; + _seqTo = 0; + + _seqCounter = _seqcounter2 = 0; + _seqStack = 0; + _frameNumber = -1; + + if (_images == nullptr || _images->size() == 0) { + _type = NO_SHAPE; + } else { + _type = ACTIVE_BG_SHAPE; + int idx = _sequences[0]; + if (idx >= _maxFrames) + // Turn on: set up first frame + idx = 0; + + _imageFrame = &(*_images)[idx]; + } + } +} + /*----------------------------------------------------------------*/ void CAnim::synchronize(Common::SeekableReadStream &s) { diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 31d9520932..f3879b1143 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -49,9 +49,31 @@ enum SpriteType { HIDE_SHAPE = 8 // Object needs to be hidden }; +enum AType { + OBJECT = 0, + PERSON = 1, + SOLID = 2, + TALK = 3, // Standard talk zone + FLAG_SET = 4, + DELTA = 5, + WALK_AROUND = 6, + TALK_EVERY = 7, // Talk zone that turns on every room visit + TALK_MOVE = 8, // Talk zone that only activates when Holmes moves + PAL_CHANGE = 9, // Changes the palette down so that it gets darker + PAL_CHANGE2 = 10, // Same as PAL_CHANGE, except that it goes up + SCRIPT_ZONE = 11, // If this is clicked in, it is activated + BLANK_ZONE = 12, // This masks out other objects when entered + NOWALK_ZONE = 13 // Player cannot walk here +}; + #define MAX_HOLMES_SEQUENCE 16 #define MAX_FRAME 30 +// code put into sequences to defines 1-10 type seqs +#define SEQ_TO_CODE 67 +#define FLIP_CODE (64 + 128) +#define SOUND_CODE (34 + 128) + struct Sprite { Common::String _name; // Name Common::String _description; // Description @@ -131,7 +153,7 @@ struct Object { int _maxFrames; // Number of frames int _flags; // Tells if object can be walked behind ActionType _aOpen; // Holds data for moving object - int _aType; // Tells if this is an object, person, talk, etc. + AType _aType; // Tells if this is an object, person, talk, etc. int _lookFrames; // How many frames to play of the look anim before pausing int _seqCounter; // How many times this sequence has been executed Common::Point _lookPosition; // Where to walk when examining object @@ -147,6 +169,8 @@ struct Object { UseType _use[4]; void synchronize(Common::SeekableReadStream &s); + + void toggleHidden(); }; struct CAnim { diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index ffae6f60c1..86e347d011 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -46,18 +46,47 @@ void BgfileheaderInfo::synchronize(Common::SeekableReadStream &s) { _filename = Common::String(buffer); } -int _fSize; // How long images are -int _maxFrames; // How many unique frames in object -Common::String _filename; // Filename of object +/*----------------------------------------------------------------*/ + +void Exit::synchronize(Common::SeekableReadStream &s) { + _position.x = s.readSint16LE(); + _position.y = s.readSint16LE(); + _size.x = s.readSint16LE(); + _size.y = s.readSint16LE(); + _scene = s.readSint16LE(); + _allow = s.readSint16LE(); + _people.x = s.readSint16LE(); + _people.y = s.readSint16LE(); + _peopleDir = s.readUint16LE(); +} + +/*----------------------------------------------------------------*/ + +void SceneEntry::synchronize(Common::SeekableReadStream &s) { + _startPosition.x = s.readSint16LE(); + _startPosition.y = s.readSint16LE(); + _startDir = s.readByte(); + _allow = s.readByte(); +} + +void SceneSound::synchronize(Common::SeekableReadStream &s) { + char buffer[9]; + s.read(buffer, 8); + buffer[8] = '\0'; + + _name = Common::String(buffer); + _priority = s.readByte(); +} /*----------------------------------------------------------------*/ Scene::Scene(SherlockEngine *vm): _vm(vm) { for (int idx = 0; idx < SCENES_COUNT; ++idx) Common::fill(&_stats[idx][0], &_stats[idx][9], false); + _currentScene = -1; _goToRoom = -1; + _changes = false; _oldCharPoint = 0; - _numExits = 0; _windowOpen = _infoFlag = false; _menuMode = _keyboardInput = 0; _walkedInScene = false; @@ -66,10 +95,12 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { _lzwMode = false; _invGraphicItems = 0; + _controlPanel = new ImageFile("controls.vgs"); _controls = nullptr; // new ImageFile("menu.all"); } Scene::~Scene() { + delete _controlPanel; delete _controls; clear(); } @@ -78,13 +109,10 @@ Scene::~Scene() { * Takes care of clearing any scene data */ void Scene::clear() { - for (uint idx = 0; idx < _bgShapes.size(); ++idx) - delete _bgShapes[idx]._images; } void Scene::selectScene() { // Reset fields - _numExits = 0; _windowOpen = _infoFlag = false; _menuMode = _keyboardInput = 0; _oldKey = _help = _oldHelp = 0; @@ -93,6 +121,7 @@ void Scene::selectScene() { // Load the scene Common::String sceneFile = Common::String::format("res%02d", _goToRoom); Common::String roomName = Common::String::format("res%02d.rrm", _goToRoom); + _currentScene = _goToRoom; _goToRoom = -1; loadScene(sceneFile); @@ -108,6 +137,8 @@ void Scene::selectScene() { * that it should point to after loading; _misc is then set to 0. */ void Scene::loadScene(const Common::String &filename) { + Screen &screen = *_vm->_screen; + Sound &sound = *_vm->_sound; bool flag; _walkedInScene = false; @@ -240,11 +271,160 @@ void Scene::loadScene(const Common::String &filename) { // Back at version byte, so skip over it rrmStream->skip(1); - // TODO + // Load the walk directory + for (int idx1 = 0; idx1 < MAX_ZONES; ++idx1) { + for (int idx2 = 0; idx2 < MAX_ZONES; ++idx2) + _walkDirectory[idx1][idx2] = rrmStream->readSint16LE(); + } + + // Read in the walk data + size = rrmStream->readUint16LE(); + Common::SeekableReadStream *walkStream = !_lzwMode ? rrmStream : + decompressLZ(*rrmStream, size); + + _walkData.resize(size); + walkStream->read(&_walkData[0], size); + + if (_lzwMode) + delete walkStream; + + // Read in the exits + int numExits = rrmStream->readByte(); + _exits.resize(numExits); + + for (int idx = 0; idx < numExits; ++idx) + _exits[idx].synchronize(*rrmStream); + + // Read in the entrance + _entrance.synchronize(*rrmStream); + + // Initialize sound list + int numSounds = rrmStream->readByte(); + _sounds.resize(numSounds); + + for (int idx = 0; idx < numSounds; ++idx) + _sounds[idx].synchronize(*rrmStream); + + // If sound is turned on, load the sounds into memory + if (sound._sfxEnabled) { + for (int idx = 0; idx < numSounds; ++idx) { + sound.loadSound(_sounds[idx]._name, _sounds[idx]._priority); + _sounds[idx]._name = ""; + } + } + + // Read in palette + rrmStream->read(screen._cMap, PALETTE_SIZE); + for (int idx = 0; idx < PALETTE_SIZE; ++idx) + screen._cMap[idx] = VGA_COLOR_TRANS(screen._cMap[idx]); + + Common::copy(screen._cMap, screen._cMap + PALETTE_SIZE, screen._sMap); + + // Read in the background + Common::SeekableReadStream *bgStream = !_lzwMode ? rrmStream : + decompressLZ(*rrmStream, SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT); + + bgStream->read(screen._backBuffer.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT); + + if (_lzwMode) + delete bgStream; + + // Set the palette + screen._backBuffer2.blitFrom(screen._backBuffer); + screen.setPalette(screen._cMap); delete rrmStream; } + // Clear user interface area and draw controls + screen._backBuffer2.fillRect(0, INFO_LINE, SHERLOCK_SCREEN_WIDTH, INFO_LINE + 10, INFO_BLACK); + screen._backBuffer.transBlitFrom((*_controlPanel)[0], Common::Point(0, CONTROLS_Y)); + screen._backBuffer2.transBlitFrom((*_controlPanel)[0], Common::Point(0, CONTROLS_Y)); + + _changes = false; + checkSceneStatus(); + + if (!_vm->_justLoaded) { + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + if (_bgShapes[idx]._type == HIDDEN && _bgShapes[idx]._aType == TALK_EVERY) + _bgShapes[idx].toggleHidden(); + } + + // Check for TURNON objects + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + if (_bgShapes[idx]._type == HIDDEN && (_bgShapes[idx]._flags & 0x20)) + _bgShapes[idx].toggleHidden(); + } + + // Check for TURNOFF objects + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + if (_bgShapes[idx]._type != HIDDEN && (_bgShapes[idx]._flags & 0x40) && + _bgShapes[idx]._type != INVALID) + _bgShapes[idx].toggleHidden(); + } + } + + checkSceneFlags(false); + checkInventory(); + + // TODO +} + +/** + * Set objects to their current persistent state. This includes things such as + * opening or moving them + */ +void Scene::checkSceneStatus() { + if (_stats[_currentScene][8]) { + for (int idx = 0; idx < 8; ++idx) { + int val = _stats[_currentScene][idx]; + + for (int bit = 0; bit < 8; ++bit) { + uint objNumber = idx * 8 + bit; + if (objNumber < _bgShapes.size()) { + Object &obj = _bgShapes[objNumber]; + + if (val & 1) { + // No shape to erase, so flag as hidden + obj._type = HIDDEN; + } else if (obj._images == nullptr || obj._images->size() == 0) { + // No shape + obj._type = NO_SHAPE; + } else { + obj._type = ACTIVE_BG_SHAPE; + } + } else { + // Finished checks + return; + } + + val >>= 1; + } + } + } +} + +/** + * Check the scene's objects against the game flags. If false is passed, + * it means the scene has just been loaded. A value of true means that the scene + * is in use (ie. not just loaded) + */ +void Scene::checkSceneFlags(bool flag) { + int mode = mode ? HIDE_SHAPE : HIDDEN; + + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + Object &o = _bgShapes[idx]; + // TODO: read_flags calls + } +} + +/** + * Checks scene objects against the player's inventory items. If there are any + * matching names, it means the given item has already been picked up, and should + * be hidden in the scene. + */ +void Scene::checkInventory() { + } } // End of namespace Sherlock diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 2280e169b7..ae4fcfdb45 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -32,6 +32,10 @@ namespace Sherlock { #define SCENES_COUNT 63 +#define MAX_ZONES 40 +#define INFO_LINE 140 +#define CONTROLS_Y 138 +#define CONTROLS_Y1 151 class SherlockEngine; @@ -54,6 +58,33 @@ struct BgfileheaderInfo { void synchronize(Common::SeekableReadStream &s); }; +struct Exit { + Common::Point _position; + Common::Point _size; + + int _scene; + int _allow; + Common::Point _people; + int _peopleDir; + + void synchronize(Common::SeekableReadStream &s); +}; + +struct SceneEntry { + Common::Point _startPosition; + int _startDir; + int _allow; + + void synchronize(Common::SeekableReadStream &s); +}; + +struct SceneSound { + Common::String _name; + int _priority; + + void synchronize(Common::SeekableReadStream &s); +}; + class Scene { private: SherlockEngine *_vm; @@ -61,15 +92,23 @@ private: void loadScene(); void loadScene(const Common::String &filename); + + void checkSceneStatus(); + + void checkSceneFlags(bool mode); + + void checkInventory(); public: + int _currentScene; + int _goToRoom; + bool _changes; bool _stats[SCENES_COUNT][9]; bool _savedStats[SCENES_COUNT][9]; - int _goToRoom; Common::Point _bigPos; Common::Point _overPos; int _oldCharPoint; ImageFile *_controls; - int _numExits; + ImageFile *_controlPanel; bool _windowOpen, _infoFlag; int _menuMode, _keyboardInput; int _oldKey, _help, _oldHelp; @@ -86,6 +125,11 @@ public: Common::Array _cAnim; Common::Array _sequenceBuffer; Common::Array _inv; + int _walkDirectory[MAX_ZONES][MAX_ZONES]; + Common::Array _walkData; + Common::Array _exits; + SceneEntry _entrance; + Common::Array _sounds; public: Scene(SherlockEngine *vm); ~Scene(); diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 0ec5df9c4c..b322b96d6b 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -32,6 +32,8 @@ Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCR _backBuffer2(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT) { _transitionSeed = 1; _fadeStyle = false; + Common::fill(&_cMap[0], &_cMap[PALETTE_SIZE], 0); + Common::fill(&_sMap[0], &_sMap[PALETTE_SIZE], 0); setFont(1); } diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 05fd80a8b7..2c5e585475 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -34,6 +34,7 @@ namespace Sherlock { #define PALETTE_SIZE 768 #define PALETTE_COUNT 256 #define VGA_COLOR_TRANS(x) ((x) * 255 / 63) +#define INFO_BLACK 1 class SherlockEngine; @@ -52,6 +53,8 @@ protected: public: Surface _backBuffer, _backBuffer2; bool _fadeStyle; + byte _cMap[PALETTE_SIZE]; + byte _sMap[PALETTE_SIZE]; public: Screen(SherlockEngine *vm); diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index a963d0bfe5..115d9f0130 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -43,6 +43,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _useEpilogue2 = false; _hsavedPos = Common::Point(-1, -1); _hsavedFs = -1; + _justLoaded = false; } SherlockEngine::~SherlockEngine() { diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 210e24c320..c31416f91e 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -59,6 +59,7 @@ enum { #define SHERLOCK_SCREEN_WIDTH 320 #define SHERLOCK_SCREEN_HEIGHT 200 +#define SHERLOCK_SCENE_HEIGHT 138 struct SherlockGameDescription; @@ -91,6 +92,7 @@ public: bool _useEpilogue2; Common::Point _hsavedPos; int _hsavedFs; + bool _justLoaded; public: SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc); virtual ~SherlockEngine(); diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index efc1965637..61c740ea3f 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -32,6 +32,10 @@ Sound::Sound(SherlockEngine *vm): _vm(vm) { _music = false; } +void Sound::loadSound(const Common::String &name, int priority) { + // TODO +} + void Sound::playSound(const Common::String &name, WaitType waitType) { // TODO } diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index 442e908838..9d323833f1 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -46,6 +46,7 @@ public: public: Sound(SherlockEngine *vm); + void loadSound(const Common::String &name, int priority); void playSound(const Common::String &name, WaitType waitType = WAIT_RETURN_IMMEDIATELY); void cacheSound(const Common::String &name, int index); void playCachedSound(int index); -- cgit v1.2.3 From f0ad2f624bddcc031c99a487bff1d5ec89956477 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 20 Mar 2015 22:01:52 -0400 Subject: SHERLOCK: More scene loading, implemented Inventory class --- engines/sherlock/inventory.cpp | 27 ++++++++++ engines/sherlock/inventory.h | 18 +++++-- engines/sherlock/module.mk | 1 + engines/sherlock/objects.cpp | 6 +++ engines/sherlock/objects.h | 3 ++ engines/sherlock/people.cpp | 18 +++++++ engines/sherlock/people.h | 4 ++ engines/sherlock/scalpel/scalpel.cpp | 16 ++++++ engines/sherlock/scene.cpp | 96 ++++++++++++++++++++++++++++++++++-- engines/sherlock/scene.h | 10 ++-- engines/sherlock/sherlock.cpp | 24 +++++++++ engines/sherlock/sherlock.h | 9 ++++ 12 files changed, 218 insertions(+), 14 deletions(-) create mode 100644 engines/sherlock/inventory.cpp diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp new file mode 100644 index 0000000000..634e664f5a --- /dev/null +++ b/engines/sherlock/inventory.cpp @@ -0,0 +1,27 @@ +/* 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 "sherlock/inventory.h" + +namespace Sherlock { + +} // End of namespace Sherlock diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index de4a2d7758..dc56e93841 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -24,15 +24,23 @@ #define SHERLOCK_INVENTORY_H #include "common/scummsys.h" +#include "common/array.h" namespace Sherlock { struct InventoryItem { - int stringIndex; - char name[12]; - char description[41]; - char name2[9]; - uint16 value; + int _requiredFlag; + Common::String _name; + Common::String _description;; + Common::String _examine; + int _lookFlag; +}; + +class Inventory : public Common::Array { +public: + uint _holdings; + + Inventory() : Common::Array(), _holdings(0) {} }; } // End of namespace Sherlock diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk index dc88ab3f5f..aa8f495742 100644 --- a/engines/sherlock/module.mk +++ b/engines/sherlock/module.mk @@ -11,6 +11,7 @@ MODULE_OBJS = \ detection.o \ events.o \ graphics.o \ + inventory.o \ journal.o \ objects.o \ people.o \ diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index aa9b391f96..d696954cda 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -51,6 +51,12 @@ void Sprite::clear() { _numFrames = 0; } +void Sprite::setImageFrame() { + // TODO: check this + int imageNumber = (*_sequences)[_sequenceNumber][_frameNumber]; + _imageFrame = &(*_images)[imageNumber]; +} + /*----------------------------------------------------------------*/ void ActionType::synchronize(Common::SeekableReadStream &s) { diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index f3879b1143..d43b70f4e9 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -100,7 +100,10 @@ struct Sprite { int _numFrames; // How many frames the object has Sprite() { clear(); } + void clear(); + + void setImageFrame(); }; struct ActionType { diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index cdb498e5e6..b4bbef2e1a 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -46,6 +46,12 @@ static const uint8 CHARACTER_SEQUENCES[MAX_HOLMES_SEQUENCE][MAX_FRAME] = { People::People(SherlockEngine *vm) : _vm(vm) { + _walkLoaded = false; +} + +People::~People() { + if (_walkLoaded) + delete _data[PLAYER]._images; } void People::reset() { @@ -70,4 +76,16 @@ void People::reset() { p._status = 0; } +bool People::loadWalk() { + if (_walkLoaded) { + return false; + } else { + _data[PLAYER]._images = new ImageFile("walk.vgs"); + _data[PLAYER].setImageFrame(); + _walkLoaded = true; + + return true; + } +} + } // End of namespace Sherlock diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index 3f639a6d44..4bdc6a88f0 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -46,10 +46,14 @@ class People { private: SherlockEngine *_vm; Sprite _data[MAX_PEOPLE]; + bool _walkLoaded; public: People(SherlockEngine *vm); + ~People(); void reset(); + + bool loadWalk(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index ca04153594..40ca9736d6 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -27,6 +27,18 @@ namespace Sherlock { namespace Scalpel { +#define NUM_PLACES 100 +const int MAP_X[NUM_PLACES] = { + 0, 368, 0, 219, 0, 282, 0, 43, 0, 0, 396, 408, 0, 0, 0, 568, 37, 325, + 28, 0, 263, 36, 148, 469, 342, 143, 443, 229, 298, 0, 157, 260, 432, + 174, 0, 351, 0, 528, 0, 136, 0, 0, 0, 555, 165, 0, 506, 0, 0, 344, 0, 0 +}; +const int MAP_Y[NUM_PLACES] = { + 0, 147, 0, 166, 0, 109, 0, 61, 0, 0, 264, 70, 0, 0, 0, 266, 341, 30, 275, + 0, 294, 146, 311, 230, 184, 268, 133, 94, 207, 0, 142, 142, 330, 255, 0, + 37, 0, 70, 0, 116, 0, 0, 0, 50, 21, 0, 303, 0, 0, 229, 0, 0 +}; + ScalpelEngine::ScalpelEngine(OSystem *syst, const SherlockGameDescription *gameDesc) : SherlockEngine(syst, gameDesc) { _chess = nullptr; @@ -53,6 +65,10 @@ void ScalpelEngine::initialize() { _flags[3] = true; // Turn on Alley _flags[39] = true; // Turn on Baker Street + // Load the map co-ordinates for each scene + for (int idx = 0; idx < NUM_PLACES; ++idx) + _map.push_back(Common::Point(MAP_X[idx], MAP_Y[idx])); + // Starting scene _scene->_goToRoom = 4; } diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 86e347d011..4ec5c29134 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -136,7 +136,9 @@ void Scene::selectScene() { * The _misc field of the structures contains the number of the graphic image * that it should point to after loading; _misc is then set to 0. */ -void Scene::loadScene(const Common::String &filename) { +bool Scene::loadScene(const Common::String &filename) { + EventsManager &events = *_vm->_events; + People &people = *_vm->_people; Screen &screen = *_vm->_screen; Sound &sound = *_vm->_sound; bool flag; @@ -367,7 +369,28 @@ void Scene::loadScene(const Common::String &filename) { checkSceneFlags(false); checkInventory(); - // TODO + // Handle starting any music for the scene + if (sound._musicEnabled && sound.loadSong(_currentScene)) { + if (sound._music) + sound.startSong(); + } + + // Load walking images if not already loaded + people.loadWalk(); + + // Transition to the scene and setup entrance co-ordinates and animations + transitionToScene(); + + // Player has not yet walked in this scene + _walkedInScene = false; + + // Reset the position on the overland map + _vm->_oldCharPoint = _currentScene; + _vm->_over.x = _vm->_map[_currentScene].x * 100 - 600; + _vm->_over.y = _vm->_map[_currentScene].y * 100 + 900; + + events.clearEvents(); + return flag; } /** @@ -410,11 +433,55 @@ void Scene::checkSceneStatus() { * is in use (ie. not just loaded) */ void Scene::checkSceneFlags(bool flag) { - int mode = mode ? HIDE_SHAPE : HIDDEN; + SpriteType mode = flag ? HIDE_SHAPE : HIDDEN; for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; - // TODO: read_flags calls + + if (o._requiredFlag) { + if (!_vm->readFlags(_bgShapes[idx]._requiredFlag)) { + // Kill object + if (o._type != HIDDEN && o._type != INVALID) { + if (o._images == nullptr || o._images->size() == 0) + // No shape to erase, so flag as hidden + o._type = HIDDEN; + else + // Flag it as needing to be hidden after first erasing it + o._type = mode; + } + } else if (_bgShapes[idx]._requiredFlag) { + // Restore object + if (o._images == nullptr || o._images->size() == 0) + o._type = NO_SHAPE; + else + o._type = ACTIVE_BG_SHAPE; + } + } + } + + // Check inventory + for (uint idx = 0; idx < _vm->_inventory->_holdings; ++idx) { + InventoryItem &ii = (*_vm->_inventory)[idx]; + if (ii._requiredFlag && !_vm->readFlags(ii._requiredFlag)) { + // Kill object: move it after the active holdings + InventoryItem tempItem = (*_vm->_inventory)[idx]; + _vm->_inventory->insert_at(_vm->_inventory->_holdings, tempItem); + _vm->_inventory->remove_at(idx); + _vm->_inventory->_holdings--; + break; + } + } + + for (uint idx = _vm->_inventory->_holdings; idx < _vm->_inventory->size(); ++idx) { + InventoryItem &ii = (*_vm->_inventory)[idx]; + if (ii._requiredFlag && _vm->readFlags(ii._requiredFlag)) { + // Restore object: move it after the active holdings + InventoryItem tempItem = (*_vm->_inventory)[idx]; + _vm->_inventory->remove_at(idx); + _vm->_inventory->insert_at(_vm->_inventory->_holdings, tempItem); + _vm->_inventory->_holdings++; + break; + } } } @@ -424,7 +491,28 @@ void Scene::checkSceneFlags(bool flag) { * be hidden in the scene. */ void Scene::checkInventory() { + for (uint shapeIdx = 0; shapeIdx < _bgShapes.size(); ++shapeIdx) { + for (uint invIdx = 0; invIdx < _vm->_inventory->size(); ++invIdx) { + if (scumm_stricmp(_bgShapes[shapeIdx]._name.c_str(), + (*_vm->_inventory)[invIdx]._name.c_str()) == 0) { + _bgShapes[shapeIdx]._type = INVALID; + break; + } + } + } +} + +/** + * Set up any entrance co-ordinates or entrance canimations, and then transition + * in the scene + */ +void Scene::transitionToScene() { + const int FS_TRANS[8] = { + STOP_UP, STOP_UPRIGHT, STOP_RIGHT, STOP_DOWNRIGHT, STOP_DOWN, + STOP_DOWNLEFT, STOP_LEFT, STOP_UPLEFT + }; + // TODO } } // End of namespace Sherlock diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index ae4fcfdb45..d51856b508 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -89,15 +89,13 @@ class Scene { private: SherlockEngine *_vm; - void loadScene(); - - void loadScene(const Common::String &filename); + bool loadScene(const Common::String &filename); void checkSceneStatus(); - void checkSceneFlags(bool mode); - void checkInventory(); + + void transitionToScene(); public: int _currentScene; int _goToRoom; @@ -137,6 +135,8 @@ public: void clear(); void selectScene(); + + void checkSceneFlags(bool mode); }; } // End of namespace Sherlock diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 115d9f0130..65dc6c80a5 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -33,6 +33,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _animation = nullptr; _debugger = nullptr; _events = nullptr; + _inventory = nullptr; _journal = nullptr; _people = nullptr; _res = nullptr; @@ -50,6 +51,7 @@ SherlockEngine::~SherlockEngine() { delete _animation; delete _debugger; delete _events; + delete _inventory; delete _journal; delete _people; delete _res; @@ -82,6 +84,7 @@ void SherlockEngine::initialize() { _animation = new Animation(this); _debugger = new Debugger(this); _events = new EventsManager(this); + _inventory = new Inventory(); _journal = new Journal(); _people = new People(this); _scene = new Scene(this); @@ -116,4 +119,25 @@ Common::Error SherlockEngine::run() { return Common::kNoError; } +/** + * Read the state of a global flag + */ +bool SherlockEngine::readFlags(int flagNum) { + bool value = _flags[ABS(flagNum)]; + if (flagNum < 0) + value = !value; + + return value; +} + +/** + * Sets a global flag to either true or false depending on whether the specified + * flag is positive or negative + */ +void SherlockEngine::setFlags(int flagNum) { + _flags[ABS(flagNum)] = flagNum >= 0; + + _scene->checkSceneFlags(true); +} + } // End of namespace Comet diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index c31416f91e..a8ca9abbfd 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -34,6 +34,7 @@ #include "sherlock/animation.h" #include "sherlock/debugger.h" #include "sherlock/events.h" +#include "sherlock/inventory.h" #include "sherlock/journal.h" #include "sherlock/people.h" #include "sherlock/resources.h" @@ -78,6 +79,7 @@ public: Animation *_animation; Debugger *_debugger; EventsManager *_events; + Inventory *_inventory; Journal *_journal; People *_people; Resources *_res; @@ -93,6 +95,9 @@ public: Common::Point _hsavedPos; int _hsavedFs; bool _justLoaded; + int _oldCharPoint; // Old scene + Common::Point _over; // Old map position + Common::Array _map; // Map locations for each scene public: SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc); virtual ~SherlockEngine(); @@ -108,6 +113,10 @@ public: Common::String getGameFile(int fileType); int getRandomNumber(int limit) { return _randomSource.getRandomNumber(limit - 1); } + + bool readFlags(int flagNum); + + void setFlags(int flagNum); }; } // End of namespace Sherlock -- cgit v1.2.3 From 06fbefc7875b37dd531b65c42087e4e6782c03a6 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 21 Mar 2015 09:20:39 -0400 Subject: SHERLOCK: Beginnings of transitionToScene --- engines/sherlock/objects.cpp | 12 ++++ engines/sherlock/objects.h | 6 ++ engines/sherlock/people.cpp | 1 + engines/sherlock/people.h | 13 +++- engines/sherlock/scalpel/scalpel.cpp | 4 +- engines/sherlock/scene.cpp | 117 +++++++++++++++++++++++++++++++++++ engines/sherlock/scene.h | 6 ++ engines/sherlock/sherlock.cpp | 3 +- engines/sherlock/sherlock.h | 3 +- 9 files changed, 157 insertions(+), 8 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index d696954cda..3fc9901a38 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -57,6 +57,18 @@ void Sprite::setImageFrame() { _imageFrame = &(*_images)[imageNumber]; } +void Sprite::adjustSprite(bool onChessboard) { + // TODO +} + +void Sprite::gotoStand() { + // TODO +} + +void Sprite::setWalking() { + // TODO +} + /*----------------------------------------------------------------*/ void ActionType::synchronize(Common::SeekableReadStream &s) { diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index d43b70f4e9..a1bdc5933c 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -104,6 +104,12 @@ struct Sprite { void clear(); void setImageFrame(); + + void adjustSprite(bool onChessboard = false); + + void gotoStand(); + + void setWalking(); }; struct ActionType { diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index b4bbef2e1a..b187b65ad4 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -47,6 +47,7 @@ static const uint8 CHARACTER_SEQUENCES[MAX_HOLMES_SEQUENCE][MAX_FRAME] = { People::People(SherlockEngine *vm) : _vm(vm) { _walkLoaded = false; + _holmesOn = true; } People::~People() { diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index 4bdc6a88f0..74a4575af6 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -28,8 +28,13 @@ namespace Sherlock { -#define MAX_PEOPLE 2 -#define PLAYER 0 +// People definitions +enum PeopleId { + PLAYER = 0, + AL = 0, + PEG = 1, + MAX_PEOPLE = 2 +}; // Animation sequence identifiers for characters enum { @@ -47,6 +52,8 @@ private: SherlockEngine *_vm; Sprite _data[MAX_PEOPLE]; bool _walkLoaded; +public: + bool _holmesOn; public: People(SherlockEngine *vm); ~People(); @@ -54,6 +61,8 @@ public: void reset(); bool loadWalk(); + + Sprite &operator[](PeopleId id) { return _data[id]; } }; } // End of namespace Sherlock diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 40ca9736d6..2477f2894f 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -193,8 +193,8 @@ void ScalpelEngine::startScene() { _scene->_goToRoom = _chess->doChessBoard(); _sound->freeSong(); - _hsavedPos = Common::Point(-1, -1); - _hsavedFs = -1; + _scene->_hsavedPos = Common::Point(-1, -1); + _scene->_hsavedFs = -1; } // Some rooms are prologue cutscenes, rather than normal game scenes. These are: diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 4ec5c29134..8875327dcf 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -94,6 +94,8 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { _version = 0; _lzwMode = false; _invGraphicItems = 0; + _hsavedPos = Common::Point(-1, -1); + _hsavedFs = -1; _controlPanel = new ImageFile("controls.vgs"); _controls = nullptr; // new ImageFile("menu.all"); @@ -511,8 +513,123 @@ void Scene::transitionToScene() { STOP_UP, STOP_UPRIGHT, STOP_RIGHT, STOP_DOWNRIGHT, STOP_DOWN, STOP_DOWNLEFT, STOP_LEFT, STOP_UPLEFT }; + People &people = *_vm->_people; + + if (_hsavedPos.x < 1) { + // No exit information from last scene-check entrance info + if (_entrance._startPosition.x < 1) { + // No entrance info either, so use defaults + _hsavedPos = Common::Point(16000, 10000); + _hsavedFs = 4; + } else { + // setup entrance info + _hsavedPos = _entrance._startPosition; + _hsavedFs = _entrance._startDir; + } + } else { + // Exit information exists, translate it to real sequence info + // Note: If a savegame was just loaded, then the data is already correct. + // Otherwise, this is a linked scene or entrance info, and must be translated + if (_hsavedFs < 8 && !_vm->_justLoaded) { + _hsavedFs = FS_TRANS[_hsavedFs]; + _hsavedPos.x *= 100; + _hsavedPos.y *= 100; + } + } + + int startcAnimNum = -1; + + if (_hsavedFs < 101) { + // Standard info, so set it + people[PLAYER]._position = _hsavedPos; + people[PLAYER]._sequenceNumber = _hsavedFs; + } else { + // It's canimation information + startcAnimNum = _hsavedFs - 101; + + // Prevent Holmes from being drawn + people[PLAYER]._position = Common::Point(0, 0); + } + + for (uint objIdx = 0; objIdx < _bgShapes.size(); ++objIdx) { + Object &obj = _bgShapes[objIdx]; + + if (obj._aType > 1 && obj._type != INVALID && obj._type != HIDDEN) { + Common::Point topLeft = obj._position; + Common::Point bottomRight; + + if (obj._type != NO_SHAPE) { + topLeft += obj._imageFrame->_position; + bottomRight.x = topLeft.x + obj._imageFrame->_frame.w; + bottomRight.y = topLeft.y + obj._imageFrame->_frame.h; + } else { + bottomRight = topLeft + obj._noShapeSize; + } + + if (Common::Rect(topLeft.x, topLeft.y, bottomRight.x, bottomRight.y).contains( + Common::Point(people[PLAYER]._position.x / 100, people[PLAYER]._position.y / 100))) { + // Current point is already inside box - impact occurred on + // a previous call. So simply do nothing except talk until the + // player is clear of the box + switch (obj._aType) { + case FLAG_SET: + for (int useNum = 0; useNum < 4; ++useNum) { + if (obj._use[useNum]._useFlag) { + if (!_vm->readFlags(obj._use[useNum]._useFlag)) + _vm->setFlags(obj._use[useNum]._useFlag); + } + + if (!_vm->_talkToAbort) { + for (int nameIdx = 0; nameIdx < 4; ++nameIdx) { + toggleObject(obj._use[useNum]._names[nameIdx]); + } + } + } + + obj._type = HIDDEN; + break; + + default: + break; + } + } + } + } + updateBackground(); // TODO } +/** + * Scans through the object list to find one with a matching name, and will + * call toggleHidden with all matches found. Returns the numer of matches found + */ +int Scene::toggleObject(const Common::String &name) { + int count = 0; + + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + if (scumm_stricmp(name.c_str(), _bgShapes[idx]._name.c_str()) == 0) { + ++count; + _bgShapes[idx].toggleHidden(); + } + } + + return count; +} + +/** + * Update the screen back buffer with all of the scene objects which need + * to be drawn + */ +void Scene::updateBackground() { + People &people = *_vm->_people; + //setDisplayBounds(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT); + + // Update Holmes if he's turned on + if (people._holmesOn) + people[AL].adjustSprite(); + + +} + } // End of namespace Sherlock diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index d51856b508..5625bb1f5b 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -96,6 +96,10 @@ private: void checkInventory(); void transitionToScene(); + + int toggleObject(const Common::String &name); + + void updateBackground(); public: int _currentScene; int _goToRoom; @@ -128,6 +132,8 @@ public: Common::Array _exits; SceneEntry _entrance; Common::Array _sounds; + Common::Point _hsavedPos; + int _hsavedFs; public: Scene(SherlockEngine *vm); ~Scene(); diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 65dc6c80a5..60e32bda82 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -42,9 +42,8 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _sound = nullptr; _talk = nullptr; _useEpilogue2 = false; - _hsavedPos = Common::Point(-1, -1); - _hsavedFs = -1; _justLoaded = false; + _talkToAbort = false; } SherlockEngine::~SherlockEngine() { diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index a8ca9abbfd..84b6c48f12 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -92,12 +92,11 @@ public: Common::String _soundOverride; Common::String _titleOverride; bool _useEpilogue2; - Common::Point _hsavedPos; - int _hsavedFs; bool _justLoaded; int _oldCharPoint; // Old scene Common::Point _over; // Old map position Common::Array _map; // Map locations for each scene + bool _talkToAbort; public: SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc); virtual ~SherlockEngine(); -- cgit v1.2.3 From b6076dd52458320f39442bc225ef8b0ce531ea51 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 21 Mar 2015 11:24:35 -0400 Subject: SHERLOCK: Implemented setWalking --- engines/sherlock/objects.cpp | 17 ++-- engines/sherlock/objects.h | 18 ++-- engines/sherlock/people.cpp | 204 +++++++++++++++++++++++++++++++++++++++++- engines/sherlock/people.h | 20 ++++- engines/sherlock/scene.cpp | 2 +- engines/sherlock/scene.h | 2 +- engines/sherlock/sherlock.cpp | 15 +--- engines/sherlock/sherlock.h | 1 + 8 files changed, 240 insertions(+), 39 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 3fc9901a38..63e4bdf621 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -21,9 +21,14 @@ */ #include "sherlock/objects.h" +#include "sherlock/sherlock.h" +#include "sherlock/people.h" +#include "sherlock/scene.h" namespace Sherlock { +SherlockEngine *Sprite::_vm; + /** * Reset the data for the sprite */ @@ -39,7 +44,7 @@ void Sprite::clear() { _allow = 0; _frameNumber = _sequenceNumber = 0; _position.x = _position.y = 0; - _movement.x = _movement.y = 0; + _delta.x = _delta.y = 0; _oldPosition.x = _oldPosition.y = 0; _oldSize.x = _oldSize.y = 0; _goto.x = _goto.y = 0; @@ -57,15 +62,7 @@ void Sprite::setImageFrame() { _imageFrame = &(*_images)[imageNumber]; } -void Sprite::adjustSprite(bool onChessboard) { - // TODO -} - -void Sprite::gotoStand() { - // TODO -} - -void Sprite::setWalking() { +void Sprite::adjustSprite() { // TODO } diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index a1bdc5933c..b1207867e4 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -74,7 +74,10 @@ enum AType { #define FLIP_CODE (64 + 128) #define SOUND_CODE (34 + 128) -struct Sprite { +class Sprite { +private: + static SherlockEngine *_vm; +public: Common::String _name; // Name Common::String _description; // Description Common::StringArray _examine; // Examine in-depth description @@ -88,7 +91,7 @@ struct Sprite { int _frameNumber; // Frame number in rame sequence to draw int _sequenceNumber; // Sequence being used Common::Point _position; // Current position - Common::Point _movement; // Momvement amount + Common::Point _delta; // Momvement delta Common::Point _oldPosition; // Old position Common::Point _oldSize; // Image's old size Common::Point _goto; // Walk destination @@ -98,18 +101,15 @@ struct Sprite { int _status; // Status: open/closed, moved/not moved int8 _misc; // Miscellaneous use int _numFrames; // How many frames the object has - +public: Sprite() { clear(); } - + static void setVm(SherlockEngine *vm) { _vm = vm; } + void clear(); void setImageFrame(); - void adjustSprite(bool onChessboard = false); - - void gotoStand(); - - void setWalking(); + void adjustSprite(); }; struct ActionType { diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index b187b65ad4..998fe4f0cf 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -21,9 +21,15 @@ */ #include "sherlock/people.h" +#include "sherlock/sherlock.h" namespace Sherlock { +// Walk speeds +#define MWALK_SPEED 2 +#define XWALK_SPEED 4 +#define YWALK_SPEED 1 + // Characer animation sequences static const uint8 CHARACTER_SEQUENCES[MAX_HOLMES_SEQUENCE][MAX_FRAME] = { { 29, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Right @@ -45,9 +51,11 @@ static const uint8 CHARACTER_SEQUENCES[MAX_HOLMES_SEQUENCE][MAX_FRAME] = { }; -People::People(SherlockEngine *vm) : _vm(vm) { +People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) { _walkLoaded = false; _holmesOn = true; + _oldWalkSequence = -1; + _allowWalkAbort = false; } People::~People() { @@ -65,7 +73,7 @@ void People::reset() { p._sequences = &CHARACTER_SEQUENCES; p._imageFrame = nullptr; p._frameNumber = 1; - p._movement = Common::Point(0, 0); + p._delta = Common::Point(0, 0); p._oldPosition = Common::Point(0, 0); p._oldSize = Common::Point(0, 0); p._misc = 0; @@ -89,4 +97,196 @@ bool People::loadWalk() { } } +/** +* Set the variables for moving a character from one poisition to another +* in a straight line - goAllTheWay must have been previously called to +* check for any obstacles in the path. +*/ +void People::setWalking() { + Scene &scene = *_vm->_scene; + int oldDirection, oldFrame; + Common::Point speed, delta; + int temp; + + // Flag that player has now walked in the scene + scene._walkedInScene = true; + + // Stop any previous walking, since a new dest is being set + _player._walkCount = 0; + oldDirection = _player._sequenceNumber; + oldFrame = _player._frameNumber; + + // Set speed to use horizontal and vertical movement + if (_vm->_onChessboard) { + speed = Common::Point(MWALK_SPEED, MWALK_SPEED); + } else { + speed = Common::Point(XWALK_SPEED, YWALK_SPEED); + } + + // If the player is already close to the given destination that no + // walking is needed, move to the next straight line segment in the + // overall walking route, if there is one + for (;;) { + // Since we want the player to be centered on the destination they + // clicked, but characters draw positions start at their left, move + // the destination half the character width to draw him centered + if (_walkDest.x >= (temp = _player._imageFrame->_frame.w / 2)) + _walkDest.x -= temp; + + delta = Common::Point( + ABS(_player._position.x / 100 - _walkDest.x), + ABS(_player._position.y / 100 - _walkDest.y) + ); + + // If we're ready to move a sufficient distance, that's it. Otherwise, + // move onto the next portion of the walk path, if there is one + if ((delta.x > 3 || delta.y > 0) || _walkTo.empty()) + break; + + // Pop next walk segment off the walk route stack + _walkDest = _walkTo.pop(); + } while (!_vm->shouldQuit()); + + // If a sufficient move is being done, then start the move + if (delta.x > 3 || delta.y) { + // See whether the major movement is horizontal or vertical + if (delta.x >= delta.y) { + // Set the initial frame sequence for the left and right, as well + // as settting the delta x depending on direction + if (_walkDest.x < (_player._position.x / 100)) { + _player._sequenceNumber = _vm->_onChessboard ? MAP_LEFT : WALK_LEFT; + _player._delta.x = speed.x * -100; + } else { + _player._sequenceNumber = _vm->_onChessboard ? MAP_RIGHT : WALK_RIGHT; + _player._delta.x = speed.x * 100; + } + + // See if the x delta is too small to be divided by the speed, since + // this would cause a divide by zero error + if (delta.x >= speed.x) { + // Det the delta y + _player._delta.y = (delta.y * 100) / (delta.x / speed.x); + if (_walkDest.y < (_player._position.y / 100)) + _player._delta.y = -_player._delta.y; + + // Set how many times we should add the delta to the player's position + _player._walkCount = delta.x / speed.x; + } else { + // The delta x was less than the speed (ie. we're really close to + // the destination). So set delta to 0 so the player won't move + _player._delta = Common::Point(0, 0); + _player._position = Common::Point(_walkDest.x * 100, _walkDest.y * 100); + _player._walkCount = 1; + } + + // See if the sequence needs to be changed for diagonal walking + if (_player._delta.y > 150) { + if (!_vm->_onChessboard) { + switch (_player._sequenceNumber) { + case WALK_LEFT: + _player._sequenceNumber = WALK_DOWNLEFT; + break; + case WALK_RIGHT: + _player._sequenceNumber = WALK_DOWNRIGHT; + break; + } + } + } else if (_player._delta.y < -150) { + if (!_vm->_onChessboard) { + switch (_player._sequenceNumber) { + case WALK_LEFT: + _player._sequenceNumber = WALK_UPLEFT; + break; + case WALK_RIGHT: + _player._sequenceNumber = WALK_UPRIGHT; + break; + } + } + } + } else { + // Major movement is vertical, so set the sequence for up and down, + // and set the delta Y depending on the direction + if (_walkDest.y < (_player._position.y / 100)) { + _player._sequenceNumber = WALK_UP; + _player._delta.y = speed.y * -100; + } else { + _player._sequenceNumber = WALK_DOWN; + _player._delta.y = speed.y * 100; + } + + // If we're on the overhead map, set the sequence so we keep moving + // in the same direction + _player._sequenceNumber = (oldDirection == -1) ? MAP_RIGHT : oldDirection; + + // Set the delta x + _player._delta.x = (delta.x * 100) / (delta.y / speed.y); + if (_walkDest.x < (_player._position.x / 100)) + _player._delta.x = -_player._delta.x; + } + } + + // See if the new walk sequence is the same as the old. If it's a new one, + // we need to reset the frame number to zero so it's animation starts at + // it's beginning. Otherwise, if it's the same sequence, we can leave it + // as is, so it keeps the animation going at wherever it was up to + if (_player._sequenceNumber != _oldWalkSequence) + _player._frameNumber = 0; + _oldWalkSequence = _player._sequenceNumber; + + if (!_player._walkCount) + gotoStand(_player); + + // If the sequence is the same as when we started, then Holmes was + // standing still and we're trying to re-stand him, so reset Holmes' + // rame to the old frame number from before it was reset to 0 + if (_player._sequenceNumber == oldDirection) + _player._frameNumber = oldFrame; +} + +/** + * Bring a moving character to a standing position. If the Scalpel chessboard + * is being displayed, then the chraracter will always face down. + */ +void People::gotoStand(Sprite &sprite) { + Scene &scene = *_vm->_scene; + _walkTo.clear(); + sprite._walkCount = 0; + + switch (sprite._sequenceNumber) { + case WALK_UP: + sprite._sequenceNumber = STOP_UP; break; + case WALK_DOWN: + sprite._sequenceNumber = STOP_DOWN; break; + case TALK_LEFT: + case WALK_LEFT: + sprite._sequenceNumber = STOP_LEFT; break; + case TALK_RIGHT: + case WALK_RIGHT: + sprite._sequenceNumber = STOP_RIGHT; break; + case WALK_UPRIGHT: + sprite._sequenceNumber = STOP_UPRIGHT; break; + case WALK_UPLEFT: + sprite._sequenceNumber = STOP_UPLEFT; break; + case WALK_DOWNRIGHT: + sprite._sequenceNumber = STOP_DOWNRIGHT; break; + case WALK_DOWNLEFT: + sprite._sequenceNumber = STOP_DOWNLEFT; break; + default: + break; + } + + // Only restart frame at 0 if the sequence number has changed + if (_oldWalkSequence != -1 || sprite._sequenceNumber == STOP_UP) + sprite._frameNumber = 0; + + if (_vm->_onChessboard) { + sprite._sequenceNumber = 0; + _data[AL]._position.x = (_vm->_map[scene._charPoint].x - 6) * 100; + _data[AL]._position.y = (_vm->_map[scene._charPoint].x + 10) * 100; + } + + _oldWalkSequence = -1; + _allowWalkAbort = true; +} + } // End of namespace Sherlock diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index 74a4575af6..be9be006e8 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -24,6 +24,7 @@ #define SHERLOCK_PEOPLE_H #include "common/scummsys.h" +#include "common/stack.h" #include "sherlock/objects.h" namespace Sherlock { @@ -39,10 +40,14 @@ enum PeopleId { // Animation sequence identifiers for characters enum { WALK_RIGHT = 0, WALK_DOWN = 1, WALK_LEFT = 2, WALK_UP = 3, STOP_LEFT = 4, - STOP_DOWN = 5, STOP_RIGHT = 6, STOP_UP = 7, WALK_UPRIGHT = 8, + STOP_DOWN = 5, STOP_RIGHT = 6, STOP_UP = 7, WALK_UPRIGHT = 8, WALK_DOWNRIGHT = 9, WALK_UPLEFT = 10, WALK_DOWNLEFT = 11, STOP_UPRIGHT = 12, STOP_UPLEFT = 13, STOP_DOWNRIGHT = 14, - STOP_DOWNLEFT = 15, TALK_RIGHT = 6, TALK_LEFT = 4 + STOP_DOWNLEFT = 15, TALK_RIGHT = 6, TALK_LEFT = 4, +}; +enum { + MAP_UP = 1, MAP_UPRIGHT = 2, MAP_RIGHT = 1, MAP_DOWNRIGHT = 4, + MAP_DOWN = 5, MAP_DOWNLEFT = 6, MAP_LEFT = 2, MAP_UPLEFT = 8 }; class SherlockEngine; @@ -51,18 +56,27 @@ class People { private: SherlockEngine *_vm; Sprite _data[MAX_PEOPLE]; + Sprite &_player; bool _walkLoaded; + int _oldWalkSequence; + bool _allowWalkAbort; public: + Common::Point _walkDest; + Common::Stack _walkTo; bool _holmesOn; public: People(SherlockEngine *vm); ~People(); + Sprite &operator[](PeopleId id) { return _data[id]; } + void reset(); bool loadWalk(); - Sprite &operator[](PeopleId id) { return _data[id]; } + void setWalking(); + + void gotoStand(Sprite &sprite); }; } // End of namespace Sherlock diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 8875327dcf..13db8d9b94 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -86,7 +86,7 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { _currentScene = -1; _goToRoom = -1; _changes = false; - _oldCharPoint = 0; + _charPoint = _oldCharPoint = 0; _windowOpen = _infoFlag = false; _menuMode = _keyboardInput = 0; _walkedInScene = false; diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 5625bb1f5b..a4b94652c8 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -108,7 +108,7 @@ public: bool _savedStats[SCENES_COUNT][9]; Common::Point _bigPos; Common::Point _overPos; - int _oldCharPoint; + int _charPoint, _oldCharPoint; ImageFile *_controls; ImageFile *_controlPanel; bool _windowOpen, _infoFlag; diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 60e32bda82..2787e2b924 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -44,6 +44,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _useEpilogue2 = false; _justLoaded = false; _talkToAbort = false; + _onChessboard = false; } SherlockEngine::~SherlockEngine() { @@ -65,20 +66,8 @@ void SherlockEngine::initialize() { DebugMan.addDebugChannel(kDebugScript, "scripts", "Script debug level"); - /* - int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); - bool native_mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32")); - - MidiDriver *driver = MidiDriver::createMidi(midiDriver); - if (native_mt32) - driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); - - _midi = new MidiPlayer(this, driver); - _midi->setGM(true); - _midi->setNativeMT32(native_mt32); - */ - ImageFile::setVm(this); + Sprite::setVm(this); _res = new Resources(); _animation = new Animation(this); _debugger = new Debugger(this); diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 84b6c48f12..1607cec974 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -97,6 +97,7 @@ public: Common::Point _over; // Old map position Common::Array _map; // Map locations for each scene bool _talkToAbort; + bool _onChessboard; public: SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc); virtual ~SherlockEngine(); -- cgit v1.2.3 From 8f4b4a7bc269bf454ab90d003f1cc55104c175b6 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 21 Mar 2015 13:01:45 -0400 Subject: SHERLOCK: Implemented updateBackground --- engines/sherlock/graphics.cpp | 26 ++++++++-- engines/sherlock/graphics.h | 8 +++- engines/sherlock/objects.cpp | 104 ++++++++++++++++++++++++++++++++++++++-- engines/sherlock/objects.h | 5 ++ engines/sherlock/people.h | 2 + engines/sherlock/scene.cpp | 107 +++++++++++++++++++++++++++++++++++++++--- engines/sherlock/scene.h | 8 +++- engines/sherlock/sherlock.cpp | 3 ++ engines/sherlock/sherlock.h | 3 ++ 9 files changed, 251 insertions(+), 15 deletions(-) diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index a4990fb6c6..8c096e3c72 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -27,12 +27,22 @@ namespace Sherlock { -Surface::Surface(uint16 width, uint16 height) { +Surface::Surface(uint16 width, uint16 height): _freePixels(true) { create(width, height, Graphics::PixelFormat::createFormatCLUT8()); } +Surface::Surface(Surface &src, const Common::Rect &r) : _freePixels(false) { + setPixels(src.getBasePtr(r.left, r.top)); + w = r.width(); + h = r.height(); + pitch = src.pitch; + format = Graphics::PixelFormat::createFormatCLUT8(); +} + + Surface::~Surface() { - free(); + if (_freePixels) + free(); } /** @@ -131,9 +141,19 @@ void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &p } } - +/** + * Fill a given area of the surface with a given color + */ void Surface::fillRect(int x1, int y1, int x2, int y2, byte color) { Graphics::Surface::fillRect(Common::Rect(x1, y1, x2, y2), color); } +/** + * Return a sub-area of the surface as a new surface object. The surfaces + * are shared in common, so changes in the sub-surface affects the original. + */ +Surface Surface::getSubArea(const Common::Rect &r) { + return Surface(*this, r); +} + } // End of namespace Sherlock diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index 82c48307d7..0536c016bf 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -29,11 +29,15 @@ namespace Sherlock { class Surface : public Graphics::Surface { +private: + bool _freePixels; protected: virtual void addDirtyRect(const Common::Rect &r) {} + + Surface(Surface &src, const Common::Rect &r); public: Surface(uint16 width, uint16 height); - ~Surface(); + ~Surface(); void blitFrom(const Graphics::Surface &src); void blitFrom(const Graphics::Surface &src, const Common::Point &pt); @@ -43,6 +47,8 @@ public: bool flipped = false, int overrideColor = 0); void fillRect(int x1, int y1, int x2, int y2, byte color); + + Surface getSubArea(const Common::Rect &r); }; } // End of namespace Sherlock diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 63e4bdf621..a12939e787 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -24,9 +24,15 @@ #include "sherlock/sherlock.h" #include "sherlock/people.h" #include "sherlock/scene.h" +#include "common/util.h" namespace Sherlock { +#define UPPER_LIMIT 0 +#define LOWER_LIMIT CONTROLS_Y +#define LEFT_LIMIT 0 +#define RIGHT_LIMIT SHERLOCK_SCREEN_WIDTH + SherlockEngine *Sprite::_vm; /** @@ -56,14 +62,106 @@ void Sprite::clear() { _numFrames = 0; } +/** + * Updates the image frame poiner for the sprite + */ void Sprite::setImageFrame() { - // TODO: check this - int imageNumber = (*_sequences)[_sequenceNumber][_frameNumber]; + int imageNumber = (*_sequences)[_sequenceNumber][_frameNumber] + + (*_sequences)[_sequenceNumber][0] - 2; _imageFrame = &(*_images)[imageNumber]; } +/** + * This adjusts the sprites position, as well as it's animation sequence: + */ void Sprite::adjustSprite() { - // TODO + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + int checkFrame = _allow ? MAX_FRAME : 32000; + + if (_type == INVALID || (_type == CHARACTER && _vm->_animating)) + return; + + if (!_vm->_talkCounter && _type == CHARACTER && _walkCount) { + // Handle active movement for the sprite + _position += _delta; + --_walkCount; + + if (!_walkCount) { + // If there any points left for the character to walk to along the + // route to a destination, then move to the next point + if (!people._walkTo.empty()) { + people._walkDest = people._walkTo.pop(); + people.setWalking(); + } else { + people.gotoStand(*this); + } + } + } + + if (_type == CHARACTER && !_vm->_onChessboard) { + if ((_position.y / 100) > LOWER_LIMIT) { + _position.y = LOWER_LIMIT * 100; + people.gotoStand(*this); + } + + if ((_position.y / 100) < UPPER_LIMIT) { + _position.y = UPPER_LIMIT * 100; + people.gotoStand(*this); + } + + if ((_position.x / 100) < LEFT_LIMIT) { + _position.x = LEFT_LIMIT * 100; + people.gotoStand(*this); + } + } else if (!_vm->_onChessboard) { + _position.y = CLIP((int)_position.y, UPPER_LIMIT, LOWER_LIMIT); + _position.x = CLIP((int)_position.x, LEFT_LIMIT, RIGHT_LIMIT); + } + + if (!_vm->_onChessboard || (_vm->_slowChess = !_vm->_slowChess)) + ++_frameNumber; + + if ((*_sequences)[_sequenceNumber][_frameNumber] == 0) { + switch (_sequenceNumber) { + case STOP_UP: + case STOP_DOWN: + case STOP_LEFT: + case STOP_RIGHT: + case STOP_UPRIGHT: + case STOP_UPLEFT: + case STOP_DOWNRIGHT: + case STOP_DOWNLEFT: + // We're in a stop sequence, so reset back to the last frame, so + // the character is shown as standing still + --_frameNumber; + break; + + default: + // Move 1 past the first frame - we need to compensate, since we + // already passed the frame increment + _frameNumber = 1; + break; + } + } + + // Update the _imageFrame to point to the new frame's image + setImageFrame(); + + // Check to see if character has entered an exit zone + if (!_walkCount && scene._walkedInScene && scene._goToRoom == -1) { + Common::Rect charRect(_position.x / 100 - 5, _position.y / 100 - 2, + _position.x / 100 + 5, _position.y / 100 + 2); + Exit *exit = scene.checkForExit(charRect); + + if (exit) { + scene._hsavedPos = exit->_people; + scene._hsavedFs = exit->_peopleDir; + + if (scene._hsavedFs > 100 && scene._hsavedPos.x < 1) + scene._hsavedPos.x = 100; + } + } } /*----------------------------------------------------------------*/ diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index b1207867e4..d9f1c7409e 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -66,6 +66,11 @@ enum AType { NOWALK_ZONE = 13 // Player cannot walk here }; +// Different levels for sprites to be at +enum { + BEHIND = 0, NORMAL_BEHIND = 1, NORMAL_FORWARD = 2, FORWARD = 3 +}; + #define MAX_HOLMES_SEQUENCE 16 #define MAX_FRAME 30 diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index be9be006e8..e58fd33ef2 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -70,6 +70,8 @@ public: Sprite &operator[](PeopleId id) { return _data[id]; } + bool isHolmesActive() const { return _walkLoaded && _holmesOn; } + void reset(); bool loadWalk(); diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 13db8d9b94..9fbec6b776 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -49,10 +49,12 @@ void BgfileheaderInfo::synchronize(Common::SeekableReadStream &s) { /*----------------------------------------------------------------*/ void Exit::synchronize(Common::SeekableReadStream &s) { - _position.x = s.readSint16LE(); - _position.y = s.readSint16LE(); - _size.x = s.readSint16LE(); - _size.y = s.readSint16LE(); + int xp = s.readSint16LE(); + int yp = s.readSint16LE(); + int xSize = s.readSint16LE(); + int ySize = s.readSint16LE(); + _bounds = Common::Rect(xp, yp, xp + xSize, yp + ySize); + _scene = s.readSint16LE(); _allow = s.readSint16LE(); _people.x = s.readSint16LE(); @@ -623,13 +625,106 @@ int Scene::toggleObject(const Common::String &name) { */ void Scene::updateBackground() { People &people = *_vm->_people; - //setDisplayBounds(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT); + Screen &screen = *_vm->_screen; + Surface surface = screen._backBuffer.getSubArea( + Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); + Sprite &player = people[AL]; // Update Holmes if he's turned on if (people._holmesOn) - people[AL].adjustSprite(); + player.adjustSprite(); + + // Flag the bg shapes which need to be redrawn + checkBgShapes(player._imageFrame, Common::Point(player._position.x / 100, + player._position.y / 100)); + + // Draw all active shapes which are behind the person + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE && _bgShapes[idx]._misc == BEHIND) + surface.transBlitFrom(_bgShapes[idx]._imageFrame->_frame, + _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); + } + + // Draw all canimations which are behind the person + for (uint idx = 0; idx < _canimShapes.size(); ++idx) { + if (_canimShapes[idx]._type == ACTIVE_BG_SHAPE && _canimShapes[idx]._misc == BEHIND) + surface.transBlitFrom(_canimShapes[idx]._imageFrame->_frame, + _canimShapes[idx]._position, _canimShapes[idx]._flags & 2); + } + + // Draw all active shapes which are normal and behind the person + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE && _bgShapes[idx]._misc == NORMAL_BEHIND) + surface.transBlitFrom(_bgShapes[idx]._imageFrame->_frame, + _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); + } + + // Draw all canimations which are normal and behind the person + for (uint idx = 0; idx < _canimShapes.size(); ++idx) { + if (_canimShapes[idx]._type == ACTIVE_BG_SHAPE && _canimShapes[idx]._misc == NORMAL_BEHIND) + surface.transBlitFrom(_canimShapes[idx]._imageFrame->_frame, + _canimShapes[idx]._position, _canimShapes[idx]._flags & 2); + } + + // Draw the player if he's active + if (player._type == CHARACTER && people.isHolmesActive()) { + bool flipped = player._sequenceNumber == WALK_LEFT || player._sequenceNumber == STOP_LEFT || + player._sequenceNumber == WALK_UPLEFT || player._sequenceNumber == STOP_UPLEFT || + player._sequenceNumber == WALK_DOWNRIGHT || player._sequenceNumber == STOP_DOWNRIGHT; + + surface.transBlitFrom(player._imageFrame->_frame, + Common::Point(player._position.x / 100, player._position.y / 100), flipped); + } + // Draw all static and active shapes that are NORMAL and are in front of the player + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + if ((_bgShapes[idx]._type == ACTIVE_BG_SHAPE || _bgShapes[idx]._type == STATIC_BG_SHAPE) && + _bgShapes[idx]._misc == NORMAL_FORWARD) + surface.transBlitFrom(_bgShapes[idx]._imageFrame->_frame, + _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); + } + + // Draw all static and active canimations that are NORMAL and are in front of the player + for (uint idx = 0; idx < _canimShapes.size(); ++idx) { + if ((_canimShapes[idx]._type == ACTIVE_BG_SHAPE || _canimShapes[idx]._type == STATIC_BG_SHAPE) && + _canimShapes[idx]._misc == NORMAL_FORWARD) + surface.transBlitFrom(_canimShapes[idx]._imageFrame->_frame, + _canimShapes[idx]._position, _canimShapes[idx]._flags & 2); + } + + // Draw all static and active shapes that are FORWARD + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + _bgShapes[idx]._oldPosition = _bgShapes[idx]._position; + _bgShapes[idx]._oldSize = Common::Point(_bgShapes[idx]._imageFrame->_frame.w, + _bgShapes[idx]._imageFrame->_frame.h); + + if ((_bgShapes[idx]._type == ACTIVE_BG_SHAPE || _bgShapes[idx]._type == STATIC_BG_SHAPE) && + _bgShapes[idx]._misc == FORWARD) + surface.transBlitFrom(_bgShapes[idx]._imageFrame->_frame, + _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); + } + + // Draw all static and active canimations that are forward + for (uint idx = 0; idx < _canimShapes.size(); ++idx) { + if ((_canimShapes[idx]._type == ACTIVE_BG_SHAPE || _canimShapes[idx]._type == STATIC_BG_SHAPE) && + _canimShapes[idx]._misc == FORWARD) + surface.transBlitFrom(_canimShapes[idx]._imageFrame->_frame, + _canimShapes[idx]._position, _canimShapes[idx]._flags & 2); + } +} + +Exit *Scene::checkForExit(const Common::Rect &r) { + for (uint idx = 0; idx < _exits.size(); ++idx) { + if (_exits[idx]._bounds.intersects(r)) + return &_exits[idx]; + } + return nullptr; } +void Scene::checkBgShapes(ImageFrame *frame, const Common::Point &pt) { + // TODO +} + + } // End of namespace Sherlock diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index a4b94652c8..8986b62bf5 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -59,8 +59,7 @@ struct BgfileheaderInfo { }; struct Exit { - Common::Point _position; - Common::Point _size; + Common::Rect _bounds; int _scene; int _allow; @@ -100,6 +99,8 @@ private: int toggleObject(const Common::String &name); void updateBackground(); + + void checkBgShapes(ImageFrame *frame, const Common::Point &pt); public: int _currentScene; int _goToRoom; @@ -134,6 +135,7 @@ public: Common::Array _sounds; Common::Point _hsavedPos; int _hsavedFs; + Common::Array _canimShapes; public: Scene(SherlockEngine *vm); ~Scene(); @@ -143,6 +145,8 @@ public: void selectScene(); void checkSceneFlags(bool mode); + + Exit *checkForExit(const Common::Rect &r); }; } // End of namespace Sherlock diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 2787e2b924..257cbb2cab 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -45,6 +45,9 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _justLoaded = false; _talkToAbort = false; _onChessboard = false; + _slowChess = false; + _animating = false; + _talkCounter = 0; } SherlockEngine::~SherlockEngine() { diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 1607cec974..7ce28cfdd7 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -98,6 +98,9 @@ public: Common::Array _map; // Map locations for each scene bool _talkToAbort; bool _onChessboard; + bool _slowChess; + bool _animating; + int _talkCounter; public: SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc); virtual ~SherlockEngine(); -- cgit v1.2.3 From 26c51680741882b7ee60a0e24227e6c6918aab0e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 21 Mar 2015 18:18:12 -0400 Subject: SHERLOCK: Implemented checkObject and some support methods --- engines/sherlock/animation.cpp | 2 +- engines/sherlock/events.cpp | 11 +- engines/sherlock/events.h | 6 +- engines/sherlock/objects.cpp | 170 ++++++++++++++++++++- engines/sherlock/objects.h | 25 ++- engines/sherlock/people.cpp | 5 + engines/sherlock/people.h | 2 + engines/sherlock/resources.cpp | 12 +- engines/sherlock/resources.h | 1 + engines/sherlock/scalpel/scalpel.cpp | 6 +- engines/sherlock/scene.cpp | 285 ++++++++++++++++++++++++++++++++++- engines/sherlock/scene.h | 9 ++ engines/sherlock/sherlock.cpp | 1 + engines/sherlock/sound.cpp | 11 +- engines/sherlock/sound.h | 8 +- 15 files changed, 521 insertions(+), 33 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 2b12005079..a7f91e91cd 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -144,7 +144,7 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f Common::String::format("%s%01d", baseName.c_str(), soundNumber) : Common::String::format("%s%02d", baseName.c_str(), soundNumber); - if (sound._voicesEnabled) + if (sound._voicesOn) sound.playSound(fname); } diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index ecdbdbe8d7..69e89e7157 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -33,7 +33,7 @@ namespace Sherlock { EventsManager::EventsManager(SherlockEngine *vm) { _vm = vm; _cursorImages = nullptr; - _cursorIndex = -1; + _cursorId = INVALID_CURSOR; _frameCounter = 1; _priorFrameTime = 0; _mouseClicked = false; @@ -57,11 +57,14 @@ void EventsManager::loadCursors(const Common::String &filename) { /** * Set the cursor to show */ -void EventsManager::changeCursor(int cursorIndex) { - _cursorIndex = cursorIndex; +void EventsManager::changeCursor(CursorId cursorId) { + if (cursorId == _cursorId) + return; + + _cursorId = cursorId; // Set the cursor data - Graphics::Surface &s = (*_cursorImages)[cursorIndex]; + Graphics::Surface &s = (*_cursorImages)[cursorId]; CursorMan.replaceCursor(s.getPixels(), s.w, s.h, s.w / 2, s.h / 2, 0xff); showCursor(); diff --git a/engines/sherlock/events.h b/engines/sherlock/events.h index 0fa6bf3a5e..8965489e27 100644 --- a/engines/sherlock/events.h +++ b/engines/sherlock/events.h @@ -33,6 +33,8 @@ namespace Sherlock { #define GAME_FRAME_RATE 60 #define GAME_FRAME_TIME (1000 / GAME_FRAME_RATE) +enum CursorId { ARROW = 0, MAGNIFY = 1, WAIT = 2, INVALID_CURSOR = -1 }; + class SherlockEngine; class EventsManager { @@ -45,7 +47,7 @@ private: bool checkForNextFrameCounter(); public: - int _cursorIndex; + CursorId _cursorId; byte _mouseButtons; bool _mouseClicked; Common::Stack _pendingKeys; @@ -55,7 +57,7 @@ public: void loadCursors(const Common::String &filename); - void changeCursor(int cursorIndex); + void changeCursor(CursorId cursorId); void showCursor(); diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index a12939e787..ece96457db 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -77,7 +77,6 @@ void Sprite::setImageFrame() { void Sprite::adjustSprite() { People &people = *_vm->_people; Scene &scene = *_vm->_scene; - int checkFrame = _allow ? MAX_FRAME : 32000; if (_type == INVALID || (_type == CHARACTER && _vm->_animating)) return; @@ -202,6 +201,17 @@ void UseType::synchronize(Common::SeekableReadStream &s) { /*----------------------------------------------------------------*/ +SherlockEngine *Object::_vm; +bool Object::_countCAnimFrames; + +void Object::setVm(SherlockEngine *vm) { + _vm = vm; + _countCAnimFrames = false; +} + +/** + * Load the object data from the passed stream + */ void Object::synchronize(Common::SeekableReadStream &s) { char buffer[50]; @@ -225,8 +235,8 @@ void Object::synchronize(Common::SeekableReadStream &s) { _sequenceNumber = s.readSint16LE(); _position.x = s.readSint16LE(); _position.y = s.readSint16LE(); - _movement.x = s.readSint16LE(); - _movement.y = s.readSint16LE(); + _delta.x = s.readSint16LE(); + _delta.y = s.readSint16LE(); _type = (SpriteType)s.readUint16LE(); _oldPosition.x = s.readSint16LE(); _oldPosition.y = s.readSint16LE(); @@ -268,6 +278,9 @@ void Object::synchronize(Common::SeekableReadStream &s) { _use[idx].synchronize(s); } +/** + * Toggle the type of an object between hidden and active + */ void Object::toggleHidden() { if (_type != HIDDEN && _type != HIDE_SHAPE && _type != INVALID) { if (_seqTo != 0) @@ -303,6 +316,153 @@ void Object::toggleHidden() { } } +/** + * Check the state of the object + */ +void Object::checkObject(Object &o) { + Scene &scene = *_vm->_scene; + Sound &sound = *_vm->_sound; + int checkFrame = _allow ? MAX_FRAME : 32000; + bool codeFound; + + if (_seqTo) { + byte *ptr = &_sequences[_frameNumber]; + if (*ptr == _seqTo) { + // The sequence is completed + *ptr = _seqTo + SEQ_TO_CODE + 128; // Reset to normal + _seqTo = 0; + } else { + // Continue doing sequence + if (*ptr > _seqTo) + *ptr--; + else + *ptr++; + + return; + } + } + + ++_frameNumber; + + do { + // Check for end of sequence + codeFound = checkEndOfSequence(); + + if (_sequences[_frameNumber] >= 128 && _frameNumber < checkFrame) { + codeFound = true; + int v = _sequences[_frameNumber]; + + if (v >= 228) { + // Goto code found + v -= 228; + _seqcounter2 = _seqCounter; + _seqStack = _frameNumber + 1; + setObjSequence(v, false); + } else if (v >= SOUND_CODE && (v <= (SOUND_CODE + 29))) { + codeFound = true; + ++_frameNumber; + v -= SOUND_CODE; + + if (sound._soundOn && !_countCAnimFrames) { + if (!scene._sounds[v - 1]._name.empty() && sound._digitized) + sound.playLoadedSound(v - 1, 0); + } + } else if (v >= FLIP_CODE && v <= (FLIP_CODE + 2)) { + // Flip code + codeFound = true; + ++_frameNumber; + v -= FLIP_CODE; + + // Alter the flipped status + switch (v) { + case 0: + // Clear the flag + _flags &= ~2; + break; + case 1: + // Set the flag + _flags |= 2; + break; + case 2: + // Toggle the flag + _flags ^= 2; + break; + default: + break; + } + } else { + v -= 128; + + // 68-99 is a squence code + if (v > SEQ_TO_CODE) { + byte *p = &_sequences[_frameNumber]; + v -= SEQ_TO_CODE; // # from 1-32 + _seqTo = v; + *p = *(p - 1); + + if (*p > 128) + // If the high bit is set, convert to a real frame + *p -= (byte)(SEQ_TO_CODE - 128); + + if (*p > _seqTo) + *p -= 1; + else + *p += 1; + + // Will be incremented below to return back to original value + --_frameNumber; + v = 0; + } else if (v == 10) { + // Set delta for objects + Common::Point pt(_sequences[_frameNumber + 1], _sequences[_frameNumber + 2]); + if (pt.x > 128) + pt.x = (pt.x - 128) * -1; + else + pt.x--; + + if (pt.y > 128) + pt.y = (pt.y - 128) * -1; + else + pt.y; + + _delta = pt; + _frameNumber += 2; + } else if (v < 4) { + for (int idx = 0; idx < 4; ++idx) { + o.checkNameForCodes(_use[v]._names[idx], nullptr); + } + + if (_use[v]._useFlag) + _vm->setFlags(_use[v]._useFlag); + } + + ++_frameNumber; + } + } + } while (codeFound); +} + +bool Object::checkEndOfSequence() const { + // TODO + return false; +} + +void Object::setObjSequence(int seq, bool wait) { + // TODO +} + +/** +* Checks for codes +* @param name The name to check for codes +* @param messages If provided, any messages to be returned +* @returns 0 if no codes are found, 1 if codes were found +*/ +int Object::checkNameForCodes(const Common::String &name, Common::StringArray *messages) { + + // TODO + return 0; +} + /*----------------------------------------------------------------*/ void CAnim::synchronize(Common::SeekableReadStream &s) { @@ -318,10 +478,10 @@ void CAnim::synchronize(Common::SeekableReadStream &s) { _flags = s.readByte(); _goto.x = s.readSint16LE(); _goto.y = s.readSint16LE(); - _sequenceNumber = s.readSint16LE(); + _gotoDir = s.readSint16LE(); _teleportPos.x = s.readSint16LE(); _teleportPos.y = s.readSint16LE(); - _teleportS = s.readSint16LE(); + _teleportDir = s.readSint16LE(); } /*----------------------------------------------------------------*/ diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index d9f1c7409e..d7442f928f 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -137,7 +137,18 @@ struct UseType { void synchronize(Common::SeekableReadStream &s); }; -struct Object { +class Object { +private: + static SherlockEngine *_vm; + + bool checkEndOfSequence() const; + + void setObjSequence(int seq, bool wait); +public: + static bool _countCAnimFrames; + + static void setVm(SherlockEngine *vm); +public: Common::String _name; // Name Common::String _description; // Description Common::String _examine; // Examine in-depth description @@ -151,7 +162,7 @@ struct Object { int _sequenceNumber; // Sequence being used SpriteType _type; // Object type Common::Point _position; // Current position - Common::Point _movement; // Momvement amount + Common::Point _delta; // Momvement amount Common::Point _oldPosition; // Old position Common::Point _oldSize; // Image's old size Common::Point _goto; // Walk destination @@ -185,19 +196,23 @@ struct Object { void synchronize(Common::SeekableReadStream &s); void toggleHidden(); + + void checkObject(Object &o); + + int checkNameForCodes(const Common::String &name, Common::StringArray *messages); }; struct CAnim { Common::String _name; // Name - int _sequences[MAX_FRAME]; // Animation sequences + byte _sequences[MAX_FRAME]; // Animation sequences Common::Point _position; // Position int _size; // Size of uncompressed animation SpriteType _type; int _flags; // Tells if can be walked behind Common::Point _goto; // coords holmes should walk to before starting canim - int _sequenceNumber; + int _gotoDir; Common::Point _teleportPos; // Location Holmes shoul teleport to after - int _teleportS; // playing canim + int _teleportDir; // playing canim void synchronize(Common::SeekableReadStream &s); }; diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 998fe4f0cf..43d3422f1a 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -289,4 +289,9 @@ void People::gotoStand(Sprite &sprite) { _allowWalkAbort = true; } +void People::walkToCoords(const Common::Point &destPos, int destDir) { + // TODO + warning("TODO: walkToCoords"); +} + } // End of namespace Sherlock diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index e58fd33ef2..d2d7e92512 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -79,6 +79,8 @@ public: void setWalking(); void gotoStand(Sprite &sprite); + + void walkToCoords(const Common::Point &destPos, int destDir); }; } // End of namespace Sherlock diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index 66feca6bd5..9e25a8dd6e 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -129,7 +129,7 @@ void Resources::addToCache(const Common::String &filename) { } /** - * Adds a resource from a library file tot he cache + * Adds a resource from a library file to the cache */ void Resources::addToCache(const Common::String &filename, const Common::String &libFilename) { // Get the resource @@ -140,6 +140,16 @@ void Resources::addToCache(const Common::String &filename, const Common::String delete stream; } +/** + * Adds a given stream to the cache under the given name + */ +void Resources::addToCache(const Common::String &filename, Common::SeekableReadStream &stream) { + _cache.load(filename, stream); +} + +/** + * Returns a stream for a given file + */ Common::SeekableReadStream *Resources::load(const Common::String &filename) { // First check if the file is directly in the cache if (_cache.isCached(filename)) diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h index 2f9222c1fd..1d8c601e77 100644 --- a/engines/sherlock/resources.h +++ b/engines/sherlock/resources.h @@ -76,6 +76,7 @@ public: void addToCache(const Common::String &filename); void addToCache(const Common::String &filename, const Common::String &libFilename); + void addToCache(const Common::String &filename, Common::SeekableReadStream &stream); bool isInCache(const Common::String &filename) const { return _cache.isCached(filename); } Common::SeekableReadStream *load(const Common::String &filename); diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 2477f2894f..b8c7661966 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -183,7 +183,7 @@ bool ScalpelEngine::showOfficeCutscene() { void ScalpelEngine::startScene() { if (_scene->_goToRoom == 100 || _scene->_goToRoom == 98) { // Chessboard selection - if (_sound->_musicEnabled) { + if (_sound->_musicOn) { if (_sound->loadSong(100)) { if (_sound->_music) _sound->startSong(); @@ -208,7 +208,7 @@ void ScalpelEngine::startScene() { case 52: case 53: case 70: - if (_sound->_musicEnabled && _sound->loadSong(_scene->_goToRoom)) { + if (_sound->_musicOn && _sound->loadSong(_scene->_goToRoom)) { if (_sound->_music) _sound->startSong(); } @@ -325,7 +325,7 @@ void ScalpelEngine::startScene() { } _events->loadCursors("rmouse.vgs"); - _events->changeCursor(0); + _events->changeCursor(ARROW); if (_scene->_goToRoom == 99) { // Chess Board diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 9fbec6b776..8158dfc705 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -98,6 +98,7 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { _invGraphicItems = 0; _hsavedPos = Common::Point(-1, -1); _hsavedFs = -1; + _cAnimFramePause = 0; _controlPanel = new ImageFile("controls.vgs"); _controls = nullptr; // new ImageFile("menu.all"); @@ -124,7 +125,7 @@ void Scene::selectScene() { // Load the scene Common::String sceneFile = Common::String::format("res%02d", _goToRoom); - Common::String roomName = Common::String::format("res%02d.rrm", _goToRoom); + _rrmName = Common::String::format("res%02d.rrm", _goToRoom); _currentScene = _goToRoom; _goToRoom = -1; @@ -312,7 +313,7 @@ bool Scene::loadScene(const Common::String &filename) { _sounds[idx].synchronize(*rrmStream); // If sound is turned on, load the sounds into memory - if (sound._sfxEnabled) { + if (sound._soundOn) { for (int idx = 0; idx < numSounds; ++idx) { sound.loadSound(_sounds[idx]._name, _sounds[idx]._priority); _sounds[idx]._name = ""; @@ -374,7 +375,7 @@ bool Scene::loadScene(const Common::String &filename) { checkInventory(); // Handle starting any music for the scene - if (sound._musicEnabled && sound.loadSong(_currentScene)) { + if (sound._musicOn && sound.loadSong(_currentScene)) { if (sound._music) sound.startSong(); } @@ -516,6 +517,7 @@ void Scene::transitionToScene() { STOP_DOWNLEFT, STOP_LEFT, STOP_UPLEFT }; People &people = *_vm->_people; + Screen &screen = *_vm->_screen; if (_hsavedPos.x < 1) { // No exit information from last scene-check entrance info @@ -539,7 +541,7 @@ void Scene::transitionToScene() { } } - int startcAnimNum = -1; + int cAnimNum = -1; if (_hsavedFs < 101) { // Standard info, so set it @@ -547,7 +549,7 @@ void Scene::transitionToScene() { people[PLAYER]._sequenceNumber = _hsavedFs; } else { // It's canimation information - startcAnimNum = _hsavedFs - 101; + cAnimNum = _hsavedFs - 101; // Prevent Holmes from being drawn people[PLAYER]._position = Common::Point(0, 0); @@ -599,7 +601,22 @@ void Scene::transitionToScene() { } updateBackground(); - // TODO + + if (screen._fadeStyle) + screen.randomTransition(); + else + screen.blitFrom(screen._backBuffer); + + if (cAnimNum != -1) { + CAnim &c = _cAnim[cAnimNum]; + Common::Point pt = c._position; + + c._position = Common::Point(-1, -1); + people[AL]._position = Common::Point(0, 0); + + startCAnim(cAnimNum, 1); + c._position = pt; + } } /** @@ -722,9 +739,265 @@ Exit *Scene::checkForExit(const Common::Rect &r) { return nullptr; } +/** + * Checks all the background shapes. If a background shape is animating, + * it will flag it as needing to be drawn. If a non-animating shape is + * colliding with another shape, it will also flag it as needing drawing + */ void Scene::checkBgShapes(ImageFrame *frame, const Common::Point &pt) { + // Iterate through the shapes + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + Object &obj = _bgShapes[idx]; + if (obj._type == STATIC_BG_SHAPE || obj._type == ACTIVE_BG_SHAPE) { + if ((obj._flags & 5) == 1) { + obj._misc = (pt.y < (obj._position.y + obj._imageFrame->_frame.h - 1)) ? + NORMAL_FORWARD : NORMAL_BEHIND; + } else if (!(obj._flags & 1)) { + obj._misc = BEHIND; + } else if (obj._flags & 4) { + obj._misc = FORWARD; + } + } + } + + // Iterate through the canimshapes + for (uint idx = 0; idx < _canimShapes.size(); ++idx) { + Object &obj = _canimShapes[idx]; + if (obj._type == STATIC_BG_SHAPE || obj._type == ACTIVE_BG_SHAPE) { + if ((obj._flags & 5) == 1) { + obj._misc = (pt.y < (obj._position.y + obj._imageFrame->_frame.h - 1)) ? + NORMAL_FORWARD : NORMAL_BEHIND; + } + else if (!(obj._flags & 1)) { + obj._misc = BEHIND; + } + else if (obj._flags & 4) { + obj._misc = FORWARD; + } + } + } +} + +/** + * Attempt to start a canimation sequence. It will load the requisite graphics, and + * then copy the canim object into the _canimShapes array to start the animation. + * + * @param cAnimNum The canim object within the current scene + * @param playRate Play rate. 0 is invalid; 1=normal speed, 2=1/2 speed, etc. + * A negative playRate can also be specified to play the animation in reverse + */ +int Scene::startCAnim(int cAnimNum, int playRate) { + EventsManager &events = *_vm->_events; + People &people = *_vm->_people; + Resources &res = *_vm->_res; + Common::Point tpPos, walkPos; + int tpDir, walkDir; + int tFrames; + int gotoCode = -1; + + // Validation + if (cAnimNum >= (int)_cAnim.size()) + // number out of bounds + return -1; + if (_canimShapes.size() >= 3 || playRate == 0) + // Too many active animations, or invalid play rate + return 0; + + CAnim &cAnim = _cAnim[cAnimNum]; + if (playRate < 0) { + // Reverse direction + walkPos = cAnim._teleportPos; + walkDir = cAnim._teleportDir; + tpPos = cAnim._goto; + tpDir = cAnim._gotoDir; + } else { + // Forward direction + walkPos = cAnim._goto; + walkDir = cAnim._gotoDir; + tpPos = cAnim._teleportPos; + tpDir = cAnim._teleportDir; + } + + events.changeCursor(WAIT); + _canimShapes.push_back(Object()); + Object &cObj = _canimShapes[_canimShapes.size() - 1]; + + if (walkPos.x != -1) { + // Holmes must walk to the walk point before the cAnimation is started + if (people[AL]._position != walkPos) + people.walkToCoords(walkPos, walkDir); + } + + if (_vm->_talkToAbort) + return 1; + + // Copy the canimation into the bgShapes type canimation structure so it can be played + cObj._allow = cAnimNum + 1; // Keep track of the parent structure + cObj._name = _cAnim[cAnimNum]._name; // Copy name + + // Remove any attempt to draw object frame + if (cAnim._type == NO_SHAPE && cAnim._sequences[0] < 100) + cAnim._sequences[0] = 0; + + cObj._sequences = cAnim._sequences; + cObj._images = nullptr; + cObj._position = cAnim._position; + cObj._delta = Common::Point(0, 0); + cObj._type = cAnim._type; + cObj._flags = cAnim._flags; + + cObj._maxFrames = 0; + cObj._frameNumber = -1; + cObj._sequenceNumber = cAnimNum; + cObj._oldPosition = Common::Point(0, 0); + cObj._oldPosition = Common::Point(0, 0); + cObj._goto = Common::Point(0, 0); + cObj._status = 0; + cObj._misc = 0; + cObj._imageFrame = nullptr; + + if (cAnim._name.size() > 0 && cAnim._type != NO_SHAPE) { + if (tpPos.x != -1) + people[AL]._type = REMOVE; + + Common::String fname = cAnim._name + ".vgs"; + if (!res.isInCache(fname)) { + // Set up RRM scene data + Common::SeekableReadStream *rrmStream = res.load(_rrmName); + rrmStream->seek(44 + cAnimNum * 4); + rrmStream->seek(rrmStream->readUint32LE()); + + // Load the canimation into the cache + Common::SeekableReadStream *imgStream = !_lzwMode ? rrmStream : + decompressLZ(*rrmStream, cAnim._size); + res.addToCache(fname, *imgStream); + + if (_lzwMode) + delete imgStream; + + delete rrmStream; + } + + // Now load the resource as an image + cObj._maxFrames = cObj._images->size(); + cObj._images = new ImageFile(fname); + cObj._imageFrame = &(*cObj._images)[0]; + + int frames = 0; + if (playRate < 0) { + // Reverse direction + // Count number of frames + while (cObj._sequences[frames] && frames < MAX_FRAME) + ++frames; + } + else { + // Forward direction + Object::_countCAnimFrames = true; + + while (cObj._type == ACTIVE_BG_SHAPE) { + cObj.checkObject(_bgShapes[0]); + ++frames; + + if (frames >= 1000) + error("CAnim has infinite loop sequence"); + } + + if (frames > 1) + --frames; + + Object::_countCAnimFrames = false; + + cObj._type = cAnim._type; + cObj._frameNumber = -1; + cObj._position = cAnim._position; + cObj._delta = Common::Point(0, 0); + } + + // Return if animation has no frames in it + if (frames == 0) + return -2; + + ++frames; + int repeat = ABS(playRate); + int dir; + + if (playRate < 0) { + // Play in reverse + dir = -2; + cObj._frameNumber = frames - 3; + } else { + dir = 0; + } + + tFrames = frames - 1; + int pauseFrame = (_cAnimFramePause) ? frames - _cAnimFramePause : -1; + + while (--frames) { + if (frames == pauseFrame) + printObjDesc(_cAnimStr, true); + + doBgAnim(); + + // Repeat same frame + int temp = repeat; + while (--temp > 0) { + cObj._frameNumber--; + doBgAnim(); + } + + cObj._frameNumber += dir; + } + + people[AL]._type = CHARACTER; + } + + // Teleport to ending coordinates if necessary + if (tpPos.x != -1) { + people[AL]._position = tpPos; // Place the player + people[AL]._sequenceNumber = tpDir; + people.gotoStand(people[AL]); + } + + if (playRate < 0) + // Reverse direction - set to end sequence + cObj._frameNumber = tFrames - 1; + + if (cObj._frameNumber <= 26) + gotoCode = cObj._sequences[cObj._frameNumber + 3]; + + // Set canim to REMOVE type and free memory + cObj.checkObject(_bgShapes[0]); + + if (gotoCode > 0 && !_vm->_talkToAbort) { + _goToRoom = gotoCode; + + if (_goToRoom < 97 && _vm->_map[_goToRoom].x) { + _overPos = _vm->_map[_goToRoom]; + } + } + + people.loadWalk(); + + if (tpPos.x != -1 && !_vm->_talkToAbort) { + // Teleport to ending coordinates + people[AL]._position = tpPos; + people[AL]._sequenceNumber = tpDir; + + people.gotoStand(people[AL]); + } + + return 1; +} + +void Scene::printObjDesc(const Common::String &str, bool firstTime) { // TODO } +/** + * Animate all objects and people. + */ +void Scene::doBgAnim() { + // TODO +} } // End of namespace Sherlock diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 8986b62bf5..06ca2f4c0d 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -87,6 +87,9 @@ struct SceneSound { class Scene { private: SherlockEngine *_vm; + Common::String _rrmName; + int _cAnimFramePause; + Common::String _cAnimStr; bool loadScene(const Common::String &filename); @@ -101,6 +104,10 @@ private: void updateBackground(); void checkBgShapes(ImageFrame *frame, const Common::Point &pt); + + int startCAnim(int cAnimNum, int playRate); + + void doBgAnim(); public: int _currentScene; int _goToRoom; @@ -147,6 +154,8 @@ public: void checkSceneFlags(bool mode); Exit *checkForExit(const Common::Rect &r); + + void printObjDesc(const Common::String &str, bool firstTime); }; } // End of namespace Sherlock diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 257cbb2cab..756be22846 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -70,6 +70,7 @@ void SherlockEngine::initialize() { DebugMan.addDebugChannel(kDebugScript, "scripts", "Script debug level"); ImageFile::setVm(this); + Object::setVm(this); Sprite::setVm(this); _res = new Resources(); _animation = new Animation(this); diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index 61c740ea3f..0917f83e89 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -25,11 +25,12 @@ namespace Sherlock { Sound::Sound(SherlockEngine *vm): _vm(vm) { - _sfxEnabled = true; - _musicEnabled = true; - _voicesEnabled = true; + _soundOn = true; + _musicOn = true; + _voicesOn = true; _playingEpilogue = false; _music = false; + _digitized = false; } void Sound::loadSound(const Common::String &name, int priority) { @@ -44,6 +45,10 @@ void Sound::cacheSound(const Common::String &name, int index) { // TODO } +void Sound::playLoadedSound(int bufNum, int waitMode) { + // TODO +} + void Sound::playCachedSound(int index) { // TODO } diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index 9d323833f1..b6e645a28f 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -38,17 +38,19 @@ class Sound { private: SherlockEngine *_vm; public: - bool _sfxEnabled; - bool _musicEnabled; - bool _voicesEnabled; + bool _soundOn; + bool _musicOn; + bool _voicesOn; bool _playingEpilogue; bool _music; + bool _digitized; public: Sound(SherlockEngine *vm); void loadSound(const Common::String &name, int priority); void playSound(const Common::String &name, WaitType waitType = WAIT_RETURN_IMMEDIATELY); void cacheSound(const Common::String &name, int index); + void playLoadedSound(int bufNum, int waitMode); void playCachedSound(int index); void clearCache(); void stopSound(); -- cgit v1.2.3 From 7f04ea4425bae0ebac7e51d71dc315b965bf94c9 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 21 Mar 2015 20:25:15 -0400 Subject: SHERLOCK: Implemented checkSprite --- engines/sherlock/animation.cpp | 4 +- engines/sherlock/events.cpp | 35 ++++--- engines/sherlock/events.h | 12 ++- engines/sherlock/objects.cpp | 195 ++++++++++++++++++++++++++++++++++- engines/sherlock/objects.h | 4 + engines/sherlock/resources.cpp | 6 +- engines/sherlock/resources.h | 2 +- engines/sherlock/scalpel/scalpel.cpp | 2 +- engines/sherlock/scene.cpp | 80 +++++++++++--- engines/sherlock/scene.h | 29 +++++- engines/sherlock/screen.cpp | 4 +- engines/sherlock/sherlock.cpp | 6 +- engines/sherlock/sherlock.h | 4 +- engines/sherlock/sound.cpp | 3 + engines/sherlock/sound.h | 3 + engines/sherlock/talk.cpp | 9 +- engines/sherlock/talk.h | 10 +- 17 files changed, 355 insertions(+), 53 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index a7f91e91cd..9d32746de4 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -66,7 +66,7 @@ Animation::Animation(SherlockEngine *vm): _vm(vm) { bool Animation::playPrologue(const Common::String &filename, int minDelay, int fade, bool setPalette, int speed) { - EventsManager &events = *_vm->_events; + Events &events = *_vm->_events; Screen &screen = *_vm->_screen; Sound &sound = *_vm->_sound; int soundNumber = 0; @@ -123,7 +123,7 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f pt.x = stream->readUint16LE(); pt.y = stream->readUint16LE(); } else { - pt = images[imageFrame]._position; + pt = images[imageFrame]._offset; } // Draw the sprite diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index 69e89e7157..1a09f0600e 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -30,7 +30,7 @@ namespace Sherlock { -EventsManager::EventsManager(SherlockEngine *vm) { +Events::Events(SherlockEngine *vm) { _vm = vm; _cursorImages = nullptr; _cursorId = INVALID_CURSOR; @@ -40,14 +40,14 @@ EventsManager::EventsManager(SherlockEngine *vm) { _mouseButtons = 0; } -EventsManager::~EventsManager() { +Events::~Events() { delete _cursorImages; } /** * Load a set of cursors from the specified file */ -void EventsManager::loadCursors(const Common::String &filename) { +void Events::loadCursors(const Common::String &filename) { hideCursor(); delete _cursorImages; @@ -57,7 +57,7 @@ void EventsManager::loadCursors(const Common::String &filename) { /** * Set the cursor to show */ -void EventsManager::changeCursor(CursorId cursorId) { +void Events::setCursor(CursorId cursorId) { if (cursorId == _cursorId) return; @@ -73,28 +73,35 @@ void EventsManager::changeCursor(CursorId cursorId) { /** * Show the mouse cursor */ -void EventsManager::showCursor() { +void Events::showCursor() { CursorMan.showMouse(true); } /** * Hide the mouse cursor */ -void EventsManager::hideCursor() { +void Events::hideCursor() { CursorMan.showMouse(false); } +/** + * Returns the cursor + */ +CursorId Events::getCursor() const { + return _cursorId; +} + /** * Returns true if the mouse cursor is visible */ -bool EventsManager::isCursorVisible() { +bool Events::isCursorVisible() const { return CursorMan.isVisible(); } /** * Check for any pending events */ -void EventsManager::pollEvents() { +void Events::pollEvents() { checkForNextFrameCounter(); Common::Event event; @@ -138,7 +145,7 @@ void EventsManager::pollEvents() { * Poll for events and introduce a small delay, to allow the system to * yield to other running programs */ -void EventsManager::pollEventsAndWait() { +void Events::pollEventsAndWait() { pollEvents(); g_system->delayMillis(10); } @@ -146,7 +153,7 @@ void EventsManager::pollEventsAndWait() { /** * Check whether it's time to display the next screen frame */ -bool EventsManager::checkForNextFrameCounter() { +bool Events::checkForNextFrameCounter() { // Check for next game frame uint32 milli = g_system->getMillis(); if ((milli - _priorFrameTime) >= GAME_FRAME_TIME) { @@ -171,7 +178,7 @@ bool EventsManager::checkForNextFrameCounter() { /** * Clear any current keypress or mouse click */ -void EventsManager::clearEvents() { +void Events::clearEvents() { _pendingKeys.clear(); _mouseClicked = false; } @@ -179,12 +186,12 @@ void EventsManager::clearEvents() { /** * Delay for a given number of game frames, where each frame is 1/60th of a second */ -void EventsManager::wait(int numFrames) { +void Events::wait(int numFrames) { uint32 totalMilli = numFrames * 1000 / GAME_FRAME_RATE; delay(totalMilli); } -bool EventsManager::delay(uint32 time, bool interruptable) { +bool Events::delay(uint32 time, bool interruptable) { // Different handling for really short versus extended times if (time < 10) { // For really short periods, simply delay by the desired amount @@ -216,7 +223,7 @@ bool EventsManager::delay(uint32 time, bool interruptable) { /** * Wait for the next frame */ -void EventsManager::waitForNextFrame() { +void Events::waitForNextFrame() { _mouseClicked = false; _mouseButtons = 0; diff --git a/engines/sherlock/events.h b/engines/sherlock/events.h index 8965489e27..e939b5768f 100644 --- a/engines/sherlock/events.h +++ b/engines/sherlock/events.h @@ -37,7 +37,7 @@ enum CursorId { ARROW = 0, MAGNIFY = 1, WAIT = 2, INVALID_CURSOR = -1 }; class SherlockEngine; -class EventsManager { +class Events { private: SherlockEngine *_vm; uint32 _frameCounter; @@ -52,18 +52,20 @@ public: bool _mouseClicked; Common::Stack _pendingKeys; public: - EventsManager(SherlockEngine *vm); - ~EventsManager(); + Events(SherlockEngine *vm); + ~Events(); void loadCursors(const Common::String &filename); - void changeCursor(CursorId cursorId); + void setCursor(CursorId cursorId); void showCursor(); void hideCursor(); - bool isCursorVisible(); + CursorId getCursor() const; + + bool isCursorVisible() const; void pollEvents(); diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index ece96457db..5a93ce6869 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -33,6 +33,10 @@ namespace Sherlock { #define LEFT_LIMIT 0 #define RIGHT_LIMIT SHERLOCK_SCREEN_WIDTH +// Distance to walk around WALK_AROUND boxes +#define CLEAR_DIST_X 5 +#define CLEAR_DIST_Y 0 + SherlockEngine *Sprite::_vm; /** @@ -77,11 +81,12 @@ void Sprite::setImageFrame() { void Sprite::adjustSprite() { People &people = *_vm->_people; Scene &scene = *_vm->_scene; + Talk &talk = *_vm->_talk; if (_type == INVALID || (_type == CHARACTER && _vm->_animating)) return; - if (!_vm->_talkCounter && _type == CHARACTER && _walkCount) { + if (!talk._talkCounter && _type == CHARACTER && _walkCount) { // Handle active movement for the sprite _position += _delta; --_walkCount; @@ -163,6 +168,190 @@ void Sprite::adjustSprite() { } } +/** + * Checks the sprite's position to see if it's collided with any special objects + */ +void Sprite::checkSprite() { + Events &events = *_vm->_events; + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + Screen &screen = *_vm->_screen; + Talk &talk = *_vm->_talk; + Common::Point pt; + Common::Rect objBounds; + Common::Point spritePt(_position.x / 100, _position.y / 100); + + if (!talk._talkCounter && _type == CHARACTER) { + pt = _walkCount ? _position + _delta : _position; + pt.x /= 100; + pt.y /= 100; + + for (uint idx = 0; idx < scene._bgShapes.size() && !talk._talkToAbort; ++idx) { + Object &obj = scene._bgShapes[idx]; + + if (obj._aType > PERSON && _type != INVALID && _type != HIDDEN) { + if (_type == NO_SHAPE) { + objBounds = Common::Rect(_position.x, _position.y, + _position.x + _noShapeSize.x, _position.y + _noShapeSize.y); + } else { + int xp = _position.x + _imageFrame->_offset.x; + int yp = _position.y + _imageFrame->_offset.y; + objBounds = Common::Rect(xp, yp, + xp + _imageFrame->_frame.w, yp + _imageFrame->_frame.h); + } + } + + if (objBounds.contains(pt)) { + if (objBounds.contains(spritePt)) { + // Current point is already inside the the bounds, so impact occurred + // on a previous call. So simply do nothing until we're clear of the box + switch (obj._aType) { + case TALK_MOVE: + if (_walkCount) { + // Holmes is moving + obj._type = HIDDEN; + obj.setFlagsAndToggles(); + talk.talkTo(obj._use[0]._target); + } + break; + + case PAL_CHANGE: + case PAL_CHANGE2: + if (_walkCount) { + int palStart = atoi(obj._use[0]._names[0].c_str()) * 3; + int palLength = atoi(obj._use[0]._names[1].c_str()) * 3; + int templ = atoi(obj._use[0]._names[2].c_str()) * 3; + if (templ == 0) + templ = 100; + + // Ensure only valid palette change data found + if (palLength > 0) { + // Figure out how far into the shape Holmes is so that we + // can figure out what percentage of the original palette + // to set the current palette to + int palPercent = (pt.x - objBounds.left) * 100 / objBounds.width(); + palPercent = palPercent * templ / 100; + if (obj._aType == PAL_CHANGE) + // Invert percentage + palPercent = 100 - palPercent; + + for (int idx = palStart; idx < (palStart + palLength); ++idx) + screen._sMap[idx] = screen._cMap[idx] * palPercent / 100; + + events.pollEvents(); + screen.setPalette(screen._sMap); + } + } + break; + + case TALK: + case TALK_EVERY: + _type = HIDDEN; + obj.setFlagsAndToggles(); + talk.talkTo(obj._use[0]._target); + break; + + default: + break; + } + } else { + // New impact just occurred + switch (obj._aType) { + case BLANK_ZONE: + // A blank zone masks out all other remaining zones underneath it. + // If this zone is hit, exit the outer loop so we do not check anymore + return; + + case SOLID: + case TALK: + // Stop walking + if (obj._aType == TALK) { + obj.setFlagsAndToggles(); + talk.talkTo(obj._use[0]._target); + } else { + people.gotoStand(*this); + } + break; + + case TALK_EVERY: + if (obj._aType == TALK_EVERY) { + obj._type = HIDDEN; + obj.setFlagsAndToggles(); + talk.talkTo(obj._use[0]._target); + } else { + people.gotoStand(*this); + } + break; + + case FLAG_SET: + obj.setFlagsAndToggles(); + obj._type = HIDDEN; + break; + + case WALK_AROUND: + if (objBounds.contains(people._walkTo.top())) { + // Reached zone + people.gotoStand(*this); + } else { + // Destination not within box, walk to best corner + Common::Point walkPos; + + if (spritePt.x >= objBounds.left && spritePt.x < objBounds.right) { + // Impact occurred due to vertical movement. Determine whether to + // travel to the left or right side + if (_delta.x > 0) + // Go to right side + walkPos.x = objBounds.right + CLEAR_DIST_X; + else if (_delta.x < 0) + // Go to left side + walkPos.x = objBounds.left - CLEAR_DIST_X; + else { + // Going straight up or down. So choose best side + if (spritePt.x >= (objBounds.left + objBounds.width() / 2)) + walkPos.x = objBounds.right + CLEAR_DIST_X; + else + walkPos.x = objBounds.left - CLEAR_DIST_X; + } + + walkPos.y = (_delta.y >= 0) ? objBounds.top - CLEAR_DIST_Y : + objBounds.bottom + CLEAR_DIST_Y; + } else { + // Impact occurred due to horizontal movement + if (_delta.y > 0) + // Go to bottom of box + walkPos.y = objBounds.bottom + CLEAR_DIST_Y; + else if (_delta.y < 0) + // Go to top of box + walkPos.y = objBounds.top - CLEAR_DIST_Y; + else { + // Going straight horizontal, so choose best side + if (spritePt.y >= (objBounds.top + objBounds.height() / 2)) + walkPos.y = objBounds.bottom + CLEAR_DIST_Y; + else + walkPos.y = objBounds.top - CLEAR_DIST_Y; + } + + walkPos.x = (_delta.x >= 0) ? objBounds.left - CLEAR_DIST_X : + objBounds.right + CLEAR_DIST_X; + } + + walkPos.x += people[AL]._imageFrame->_frame.w / 2; + people._walkDest = walkPos; + people._walkTo.push(walkPos); + people.setWalking(); + } + break; + + case DELTA: + _position.x += 200; + break; + } + } + } + } + } +} + /*----------------------------------------------------------------*/ void ActionType::synchronize(Common::SeekableReadStream &s) { @@ -463,6 +652,10 @@ int Object::checkNameForCodes(const Common::String &name, Common::StringArray *m return 0; } +void Object::setFlagsAndToggles() { + // TODO +} + /*----------------------------------------------------------------*/ void CAnim::synchronize(Common::SeekableReadStream &s) { diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index d7442f928f..d099718d5b 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -115,6 +115,8 @@ public: void setImageFrame(); void adjustSprite(); + + void checkSprite(); }; struct ActionType { @@ -200,6 +202,8 @@ public: void checkObject(Object &o); int checkNameForCodes(const Common::String &name, Common::StringArray *messages); + + void setFlagsAndToggles(); }; struct CAnim { diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index 9e25a8dd6e..4b087b59b5 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -298,10 +298,10 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette) { frame._width = stream.readUint16LE() + 1; frame._height = stream.readUint16LE() + 1; frame._flags = stream.readByte(); - frame._position.x = stream.readUint16LE(); - frame._position.y = stream.readByte(); + frame._offset.x = stream.readUint16LE(); + frame._offset.y = stream.readByte(); - frame._rleEncoded = !skipPalette && (frame._position.x == 1); + frame._rleEncoded = !skipPalette && (frame._offset.x == 1); if (frame._flags & 0xFF) { // Nibble packed frame data diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h index 1d8c601e77..ab2eb82a1e 100644 --- a/engines/sherlock/resources.h +++ b/engines/sherlock/resources.h @@ -93,7 +93,7 @@ struct ImageFrame { uint16 _width, _height; int _flags; bool _rleEncoded; - Common::Point _position; + Common::Point _offset; byte _rleMarker; Graphics::Surface _frame; diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index b8c7661966..bb9c6c0bc2 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -325,7 +325,7 @@ void ScalpelEngine::startScene() { } _events->loadCursors("rmouse.vgs"); - _events->changeCursor(ARROW); + _events->setCursor(ARROW); if (_scene->_goToRoom == 99) { // Chess Board diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 8158dfc705..13315b065b 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -90,7 +90,7 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { _changes = false; _charPoint = _oldCharPoint = 0; _windowOpen = _infoFlag = false; - _menuMode = _keyboardInput = 0; + _keyboardInput = 0; _walkedInScene = false; _ongoingCans = 0; _version = 0; @@ -99,6 +99,9 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { _hsavedPos = Common::Point(-1, -1); _hsavedFs = -1; _cAnimFramePause = 0; + _menuMode = STD_MODE; + _invMode = INVMODE_0; + _restoreFlag = false; _controlPanel = new ImageFile("controls.vgs"); _controls = nullptr; // new ImageFile("menu.all"); @@ -119,7 +122,8 @@ void Scene::clear() { void Scene::selectScene() { // Reset fields _windowOpen = _infoFlag = false; - _menuMode = _keyboardInput = 0; + _menuMode = STD_MODE; + _keyboardInput = 0; _oldKey = _help = _oldHelp = 0; _oldTemp = _temp = 0; @@ -142,7 +146,7 @@ void Scene::selectScene() { * that it should point to after loading; _misc is then set to 0. */ bool Scene::loadScene(const Common::String &filename) { - EventsManager &events = *_vm->_events; + Events &events = *_vm->_events; People &people = *_vm->_people; Screen &screen = *_vm->_screen; Sound &sound = *_vm->_sound; @@ -512,12 +516,14 @@ void Scene::checkInventory() { * in the scene */ void Scene::transitionToScene() { - const int FS_TRANS[8] = { - STOP_UP, STOP_UPRIGHT, STOP_RIGHT, STOP_DOWNRIGHT, STOP_DOWN, - STOP_DOWNLEFT, STOP_LEFT, STOP_UPLEFT - }; People &people = *_vm->_people; Screen &screen = *_vm->_screen; + Talk &talk = *_vm->_talk; + + const int FS_TRANS[8] = { + STOP_UP, STOP_UPRIGHT, STOP_RIGHT, STOP_DOWNRIGHT, STOP_DOWN, + STOP_DOWNLEFT, STOP_LEFT, STOP_UPLEFT + }; if (_hsavedPos.x < 1) { // No exit information from last scene-check entrance info @@ -563,7 +569,7 @@ void Scene::transitionToScene() { Common::Point bottomRight; if (obj._type != NO_SHAPE) { - topLeft += obj._imageFrame->_position; + topLeft += obj._imageFrame->_offset; bottomRight.x = topLeft.x + obj._imageFrame->_frame.w; bottomRight.y = topLeft.y + obj._imageFrame->_frame.h; } else { @@ -583,7 +589,7 @@ void Scene::transitionToScene() { _vm->setFlags(obj._use[useNum]._useFlag); } - if (!_vm->_talkToAbort) { + if (!talk._talkToAbort) { for (int nameIdx = 0; nameIdx < 4; ++nameIdx) { toggleObject(obj._use[useNum]._names[nameIdx]); } @@ -787,9 +793,10 @@ void Scene::checkBgShapes(ImageFrame *frame, const Common::Point &pt) { * A negative playRate can also be specified to play the animation in reverse */ int Scene::startCAnim(int cAnimNum, int playRate) { - EventsManager &events = *_vm->_events; + Events &events = *_vm->_events; People &people = *_vm->_people; Resources &res = *_vm->_res; + Talk &talk = *_vm->_talk; Common::Point tpPos, walkPos; int tpDir, walkDir; int tFrames; @@ -818,7 +825,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) { tpDir = cAnim._teleportDir; } - events.changeCursor(WAIT); + events.setCursor(WAIT); _canimShapes.push_back(Object()); Object &cObj = _canimShapes[_canimShapes.size() - 1]; @@ -828,7 +835,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) { people.walkToCoords(walkPos, walkDir); } - if (_vm->_talkToAbort) + if (talk._talkToAbort) return 1; // Copy the canimation into the bgShapes type canimation structure so it can be played @@ -968,7 +975,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) { // Set canim to REMOVE type and free memory cObj.checkObject(_bgShapes[0]); - if (gotoCode > 0 && !_vm->_talkToAbort) { + if (gotoCode > 0 && !talk._talkToAbort) { _goToRoom = gotoCode; if (_goToRoom < 97 && _vm->_map[_goToRoom].x) { @@ -978,7 +985,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) { people.loadWalk(); - if (tpPos.x != -1 && !_vm->_talkToAbort) { + if (tpPos.x != -1 && !talk._talkToAbort) { // Teleport to ending coordinates people[AL]._position = tpPos; people[AL]._sequenceNumber = tpDir; @@ -997,6 +1004,51 @@ void Scene::printObjDesc(const Common::String &str, bool firstTime) { * Animate all objects and people. */ void Scene::doBgAnim() { + Events &events = *_vm->_events; + People &people = *_vm->_people; + Screen &screen = *_vm->_screen; + Sound &sound = *_vm->_sound; + Talk &talk = *_vm->_talk; + Surface surface = screen._backBuffer.getSubArea(Common::Rect(0, 0, + SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); + int cursorId = events.getCursor(); + Common::Point mousePos = events.mousePos(); + + talk._talkToAbort = false; + + // Animate the mouse cursor + if (cursorId >= WAIT) { + if (++cursorId > (WAIT + 2)) + cursorId = WAIT; + + events.setCursor((CursorId)cursorId); + } + + // Check for setting magnifying glass cursor + if (_menuMode == INV_MODE || _menuMode == USE_MODE || _menuMode == GIVE_MODE) { + if (_invMode == INVMODE_1) { + // Only show Magnifying glass cursor if it's not on the inventory command line + if (mousePos.y < CONTROLS_Y || mousePos.y >(CONTROLS_Y1 + 13)) + events.setCursor(MAGNIFY); + else + events.setCursor(ARROW); + } else { + events.setCursor(ARROW); + } + } + + if (sound._diskSoundPlaying && !*sound._soundIsOn) { + // Loaded sound just finished playing + // TODO: This is horrible.. refactor into the Sound class + delete[] sound._digiBuf; + sound._diskSoundPlaying = false; + } + + if (_restoreFlag) { + if (people[AL]._type == CHARACTER) + people[AL].checkSprite(); + } + // TODO } diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 06ca2f4c0d..f48d45c34e 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -37,6 +37,30 @@ namespace Sherlock { #define CONTROLS_Y 138 #define CONTROLS_Y1 151 +enum MenuMode { + STD_MODE = 0, + LOOK_MODE = 1, + MOVE_MODE = 2, + TALK_MODE = 3, + PICKUP_MODE = 4, + OPEN_MODE = 5, + CLOSE_MODE = 6, + INV_MODE = 7, + USE_MODE = 8, + GIVE_MODE = 9, + JOURNAL_MODE = 10, + FILES_MODE = 11, + SETUP_MODE = 12 +}; + +enum InvMode { + INVMODE_0 = 0, + INVMODE_1 = 1, + INVMODE_2 = 2, + INVMODE_3 = 3, + INVMODE_255 = 255 +}; + class SherlockEngine; struct BgFileHeader { @@ -90,6 +114,8 @@ private: Common::String _rrmName; int _cAnimFramePause; Common::String _cAnimStr; + MenuMode _menuMode; + InvMode _invMode; bool loadScene(const Common::String &filename); @@ -120,7 +146,7 @@ public: ImageFile *_controls; ImageFile *_controlPanel; bool _windowOpen, _infoFlag; - int _menuMode, _keyboardInput; + int _keyboardInput; int _oldKey, _help, _oldHelp; int _oldTemp, _temp; bool _walkedInScene; @@ -143,6 +169,7 @@ public: Common::Point _hsavedPos; int _hsavedFs; Common::Array _canimShapes; + bool _restoreFlag; public: Scene(SherlockEngine *vm); ~Scene(); diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index b322b96d6b..e6c11b8cf4 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -181,7 +181,7 @@ bool Screen::unionRectangle(Common::Rect &destRect, const Common::Rect &src1, co * Do a random pixel transition in from _backBuffer surface to the screen */ void Screen::randomTransition() { - EventsManager &events = *_vm->_events; + Events &events = *_vm->_events; const int TRANSITION_MULTIPLIER = 0x15a4e35; _dirtyRects.clear(); @@ -210,7 +210,7 @@ void Screen::randomTransition() { * Transition to the surface from _backBuffer using a vertical transition */ void Screen::verticalTransition() { - EventsManager &events = *_vm->_events; + Events &events = *_vm->_events; byte table[SHERLOCK_SCREEN_WIDTH]; Common::fill(&table[0], &table[SHERLOCK_SCREEN_WIDTH], 0); diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 756be22846..637660e001 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -43,11 +43,9 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _talk = nullptr; _useEpilogue2 = false; _justLoaded = false; - _talkToAbort = false; _onChessboard = false; _slowChess = false; _animating = false; - _talkCounter = 0; } SherlockEngine::~SherlockEngine() { @@ -75,14 +73,14 @@ void SherlockEngine::initialize() { _res = new Resources(); _animation = new Animation(this); _debugger = new Debugger(this); - _events = new EventsManager(this); + _events = new Events(this); _inventory = new Inventory(); _journal = new Journal(); _people = new People(this); _scene = new Scene(this); _screen = new Screen(this); _sound = new Sound(this); - _talk = new Talk(); + _talk = new Talk(this); } Common::Error SherlockEngine::run() { diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 7ce28cfdd7..1c95b10ff3 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -78,7 +78,7 @@ public: const SherlockGameDescription *_gameDescription; Animation *_animation; Debugger *_debugger; - EventsManager *_events; + Events *_events; Inventory *_inventory; Journal *_journal; People *_people; @@ -96,11 +96,9 @@ public: int _oldCharPoint; // Old scene Common::Point _over; // Old map position Common::Array _map; // Map locations for each scene - bool _talkToAbort; bool _onChessboard; bool _slowChess; bool _animating; - int _talkCounter; public: SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc); virtual ~SherlockEngine(); diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index 0917f83e89..e8e433fa84 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -31,6 +31,9 @@ Sound::Sound(SherlockEngine *vm): _vm(vm) { _playingEpilogue = false; _music = false; _digitized = false; + _diskSoundPlaying = false; + _soundIsOn = nullptr; + _digiBuf = nullptr; } void Sound::loadSound(const Common::String &name, int priority) { diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index b6e645a28f..3f32f2724a 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -44,6 +44,9 @@ public: bool _playingEpilogue; bool _music; bool _digitized; + bool _diskSoundPlaying; + byte *_soundIsOn; + byte *_digiBuf; public: Sound(SherlockEngine *vm); diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 3122aff95f..414f3b90a6 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -21,10 +21,17 @@ */ #include "sherlock/talk.h" +#include "sherlock/sherlock.h" namespace Sherlock { -Talk::Talk() { +Talk::Talk(SherlockEngine *vm): _vm(vm) { + _talkCounter = 0; + _talkToAbort = false; +} + +void Talk::talkTo(const Common::String &name) { + // TODO } } // End of namespace Sherlock diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index 6ffbcdd8d4..55a4c0fd69 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -37,11 +37,19 @@ public: int &operator[](int idx) { return _data[idx]; } }; +class SherlockEngine; + class Talk { +private: + SherlockEngine *_vm; public: Common::Array _history; + bool _talkToAbort; + int _talkCounter; public: - Talk(); + Talk(SherlockEngine *vm); + + void talkTo(const Common::String &name); }; } // End of namespace Sherlock -- cgit v1.2.3 From ff02c29e9c2f96ed7e36878163b4b22dc8822255 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 22 Mar 2015 00:52:02 -0400 Subject: SHERLOCK: Implemented doBgAnim --- engines/sherlock/objects.cpp | 291 +++++++++++++++++++++++++++-- engines/sherlock/objects.h | 6 +- engines/sherlock/people.cpp | 2 + engines/sherlock/people.h | 3 + engines/sherlock/scalpel/scalpel.cpp | 21 +++ engines/sherlock/scalpel/scalpel.h | 4 + engines/sherlock/scene.cpp | 348 ++++++++++++++++++++++++++++++++++- engines/sherlock/scene.h | 20 +- engines/sherlock/screen.cpp | 63 +++++++ engines/sherlock/screen.h | 12 +- engines/sherlock/sherlock.cpp | 3 +- engines/sherlock/sherlock.h | 4 +- 12 files changed, 751 insertions(+), 26 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 5a93ce6869..6b681b42e9 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -28,6 +28,8 @@ namespace Sherlock { +#define START_FRAME 0 + #define UPPER_LIMIT 0 #define LOWER_LIMIT CONTROLS_Y #define LEFT_LIMIT 0 @@ -37,6 +39,10 @@ namespace Sherlock { #define CLEAR_DIST_X 5 #define CLEAR_DIST_Y 0 +#define INFO_FOREGROUND 11 +#define INFO_BACKGROUND 1 + + SherlockEngine *Sprite::_vm; /** @@ -83,7 +89,7 @@ void Sprite::adjustSprite() { Scene &scene = *_vm->_scene; Talk &talk = *_vm->_talk; - if (_type == INVALID || (_type == CHARACTER && _vm->_animating)) + if (_type == INVALID || (_type == CHARACTER && scene._animating)) return; if (!talk._talkCounter && _type == CHARACTER && _walkCount) { @@ -457,7 +463,7 @@ void Object::synchronize(Common::SeekableReadStream &s) { _seqStack = s.readByte(); _seqTo = s.readByte(); _descOffset = s.readUint16LE(); - _seqcounter2 = s.readByte(); + _seqCounter2 = s.readByte(); _seqSize = s.readUint16LE(); s.skip(1); _aMove.synchronize(s); @@ -487,7 +493,7 @@ void Object::toggleHidden() { _sequences[_frameNumber] = _seqTo + SEQ_TO_CODE + 128; _seqTo = 0; - _seqCounter = _seqcounter2 = 0; + _seqCounter = _seqCounter2 = 0; _seqStack = 0; _frameNumber = -1; @@ -544,7 +550,7 @@ void Object::checkObject(Object &o) { if (v >= 228) { // Goto code found v -= 228; - _seqcounter2 = _seqCounter; + _seqCounter2 = _seqCounter; _seqStack = _frameNumber + 1; setObjSequence(v, false); } else if (v >= SOUND_CODE && (v <= (SOUND_CODE + 29))) { @@ -631,29 +637,290 @@ void Object::checkObject(Object &o) { } while (codeFound); } -bool Object::checkEndOfSequence() const { - // TODO - return false; +/** + * This will check to see if the object has reached the end of a sequence. + * If it has, it switch to whichever next sequence should be started. + * @returns true if the end of a sequence was reached + */ +bool Object::checkEndOfSequence() { + Screen &screen = *_vm->_screen; + int checkFrame = _allow ? MAX_FRAME : 32000; + bool result = false; + + if (_type == REMOVE || _type == INVALID) + return false; + + if (_sequences[_frameNumber] == 0 || _frameNumber >= checkFrame) { + result = true; + + if (_frameNumber >= (checkFrame - 1)) { + _frameNumber = START_FRAME; + } else { + // Determine next sequence to use + int seq = _sequences[_frameNumber + 1]; + + if (seq == 99) { + --_frameNumber; + screen._backBuffer.transBlitFrom(_imageFrame->_frame, _position); + screen._backBuffer2.transBlitFrom(_imageFrame->_frame, _position); + _type = INVALID; + } else { + setObjSequence(seq, false); + } + } + } + + if (_allow && _frameNumber == 0) { + // canimation just ended + if (_type != NO_SHAPE && _type != REMOVE) { + _type = REMOVE; + + if (!_countCAnimFrames) { + // Save details before shape is removed + _delta.x = _imageFrame->_frame.w; + _delta.y = _imageFrame->_frame.h; + _position = _imageFrame->_offset; + + // Free the images + delete _images; + } + } else { + _type = INVALID; + } + } + + return result; } +/** + * Scans through the sequences array and finds the designated sequence. + * It then sets the frame number of the start of that sequence + */ void Object::setObjSequence(int seq, bool wait) { - // TODO + Scene &scene = *_vm->_scene; + int checkFrame = _allow ? MAX_FRAME : 32000; + + if (seq >= 128) { + // Loop the sequence until the count exceeded + seq -= 128; + + ++_seqCounter; + if (_seqCounter >= seq) { + // Go to next sequence + if (_seqStack) { + _frameNumber = _seqStack; + _seqStack = 0; + _seqCounter = _seqCounter2; + _seqCounter2 = 0; + if (_frameNumber >= checkFrame) + _frameNumber = START_FRAME; + + return; + } + + _frameNumber += 2; + if (_frameNumber >= checkFrame) + _frameNumber = 0; + + _seqCounter = 0; + if (_sequences[_frameNumber] == 0) + seq = _sequences[_frameNumber + 1]; + else + return; + } else { + // Find beginning of sequence + do { + --_frameNumber; + } while (_frameNumber > 0 && _sequences[_frameNumber] != 0); + + if (_frameNumber != 0) + _frameNumber += 2; + + return; + } + } else { + // Reset sequence counter + _seqCounter = 0; + } + + int idx = 0; + int seqCc = 0; + + while (seqCc < seq && idx < checkFrame) { + ++idx; + if (_sequences[idx] == 0) { + ++seqCc; + idx += 2; + } + } + + if (idx >= checkFrame) + idx = 0; + _frameNumber = idx; + + if (wait) { + seqCc = idx; + while (_sequences[idx] != 0) + ++idx; + + idx = idx - seqCc + 2; + for (; idx > 0; --idx) + scene.doBgAnim(); + } } /** * Checks for codes * @param name The name to check for codes -* @param messages If provided, any messages to be returned +* @param messages Provides a lookup list of messages that can be printed * @returns 0 if no codes are found, 1 if codes were found */ int Object::checkNameForCodes(const Common::String &name, Common::StringArray *messages) { + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + Screen &screen = *_vm->_screen; + Talk &talk = *_vm->_talk; + bool printed = false; + char ch; + const char *p; + + scene.toggleObject(name); + + if (name.hasPrefix("*")) { + // A code was found + printed = true; + ch = toupper(name[1]); + + switch (ch) { + case 'C': + talk.talkTo(name.c_str() + 2); + break; + + case 'T': + case 'B': + case 'F': + case 'W': + // Nothing: action was already done before canimation + break; + + case 'G': + case 'A': { + // G: Have object go somewhere + // A: Add onto existing co-ordinates + Common::String sx(name.c_str() + 2, name.c_str() + 5); + Common::String sy(name.c_str() + 6, name.c_str() + 9); + + if (ch == 'G') + _position = Common::Point(atoi(sx.c_str()), atoi(sy.c_str())); + else + _position += Common::Point(atoi(sx.c_str()), atoi(sy.c_str())); + break; + } + + default: + if (ch >= '0' && ch <= '9') { + scene._goToRoom = atoi(name.c_str() + 1); + + if (scene._goToRoom < 97 && _vm->_map[scene._goToRoom].x) { + _vm->_over.x = _vm->_map[scene._goToRoom].x * 100 - 600; + _vm->_over.y = _vm->_map[scene._goToRoom].y * 100 + 900; + } + + if ((p = strchr(name.c_str(), ',')) != nullptr) { + ++p; + + Common::String s(p, p + 3); + scene._hsavedPos.x = atoi(s.c_str()); + + s = Common::String(p + 3, p + 6); + scene._hsavedPos.y = atoi(s.c_str()); + + s = Common::String(p + 6, p + 9); + scene._hsavedFs = atoi(s.c_str()); + if (scene._hsavedFs == 0) + scene._hsavedFs = 10; + } else if ((p = strchr(name.c_str(), '/')) != nullptr) { + scene._hsavedPos = Common::Point(1, 0); + scene._hsavedFs = 100 + atoi(p + 1); + } + } else { + scene._goToRoom = 100; + } + + people[AL]._position = Common::Point(0, 0); + break; + } + } else if (name.hasPrefix("!")) { + // Message attached to canimation + int messageNum = atoi(name.c_str() + 1); + scene._infoFlag++; + scene.clearInfo(); + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, INFO_BACKGROUND, + (*messages)[messageNum].c_str()); + _vm->_menuCounter = 25; + } else if (name.hasPrefix("@")) { + // Message attached to canimation + scene._infoFlag++; + scene.clearInfo(); + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, INFO_BACKGROUND, + "%s", name.c_str() + 1); + printed = true; + _vm->_menuCounter = 25; + } - // TODO - return 0; + return printed; } +/** + * Handle setting any flags associated with the object + */ void Object::setFlagsAndToggles() { - // TODO + Scene &scene = *_vm->_scene; + Talk &talk = *_vm->_talk; + + for (int useIdx = 0; useIdx < 4; ++useIdx) { + if (_use[useIdx]._useFlag) { + if (!_vm->readFlags(_use[useIdx]._useFlag)) + _vm->setFlags(_use[useIdx]._useFlag); + } + + if (_use[useIdx]._cAnimSpeed) { + if (_use[useIdx]._cAnimNum == 0) + // 0 is really a 10 + scene.startCAnim(_use[useIdx]._cAnimNum - 1, _use[useIdx]._cAnimSpeed); + } + + if (!talk._talkToAbort) { + for (int idx = 0; idx < 4; ++idx) + scene.toggleObject(_use[useIdx]._names[idx]); + } + } +} + +/** + * Adjusts the sprite's position and animation sequence, advancing by 1 frame. + * If the end of the sequence is reached, the appropriate action is taken. + */ +void Object::adjustObject() { + if (_type == REMOVE) + return; + + _position += _delta; + + if (_position.y > LOWER_LIMIT) + _position.y = LOWER_LIMIT; + + if (_type != NO_SHAPE) { + int frame = _frameNumber; + if (frame == -1) + frame = 0; + + int imgNum = _sequences[frame]; + if (imgNum > _maxFrames) + imgNum = 1; + + _imageFrame = &(*_images)[imgNum - 1]; + } } /*----------------------------------------------------------------*/ diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index d099718d5b..ee82faf99c 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -143,7 +143,7 @@ class Object { private: static SherlockEngine *_vm; - bool checkEndOfSequence() const; + bool checkEndOfSequence(); void setObjSequence(int seq, bool wait); public: @@ -190,7 +190,7 @@ public: int _seqStack; // Allows gosubs to return to calling frame int _seqTo; // Allows 1-5, 8-3 type sequences encoded in 2 bytes uint _descOffset; // Tells where description starts in DescText - int _seqcounter2; // Counter of calling frame sequence + int _seqCounter2; // Counter of calling frame sequence uint _seqSize; // Tells where description starts ActionType _aMove; UseType _use[4]; @@ -204,6 +204,8 @@ public: int checkNameForCodes(const Common::String &name, Common::StringArray *messages); void setFlagsAndToggles(); + + void adjustObject(); }; struct CAnim { diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 43d3422f1a..d2fbb3d8c5 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -56,6 +56,8 @@ People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) { _holmesOn = true; _oldWalkSequence = -1; _allowWalkAbort = false; + _portraitLoaded = false; + _clearingThePortrait = false; } People::~People() { diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index d2d7e92512..7c218671c9 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -64,6 +64,9 @@ public: Common::Point _walkDest; Common::Stack _walkTo; bool _holmesOn; + bool _portraitLoaded; + Object _portrait; + bool _clearingThePortrait; public: People(SherlockEngine *vm); ~People(); diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index bb9c6c0bc2..1fe1901212 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -336,6 +336,27 @@ void ScalpelEngine::startScene() { _chessResult = _scene->_goToRoom; } +/** + * Takes care of clearing the mirror in scene 12, in case anything drew over it + */ +void ScalpelEngine::eraseMirror12() { + // TODO +} + +/** + * Takes care of drawing Holme's reflection onto the mirror in scene 12 + */ +void ScalpelEngine::doMirror12() { + // TODO +} + +/** + * This clears the mirror in scene 12 in case anything messed draw over it + */ +void ScalpelEngine::flushMirror12() { + // TODO +} + } // End of namespace Scalpel } // End of namespace Scalpel diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h index b096599ee1..2d5deeb882 100644 --- a/engines/sherlock/scalpel/scalpel.h +++ b/engines/sherlock/scalpel/scalpel.h @@ -51,6 +51,10 @@ protected: public: ScalpelEngine(OSystem *syst, const SherlockGameDescription *gameDesc); virtual ~ScalpelEngine(); + + void eraseMirror12(); + void doMirror12(); + void flushMirror12(); }; } // End of namespace Scalpel diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 13315b065b..92a8757fd8 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -22,10 +22,42 @@ #include "sherlock/scene.h" #include "sherlock/sherlock.h" +#include "sherlock/scalpel/scalpel.h" #include "sherlock/decompress.h" namespace Sherlock { +// Main Menu control locations +const int MENU_POINTS[12][4] = { + { 13, 153, 72, 165 }, + { 13, 169, 72, 181 }, + { 13, 185, 72, 197 }, + { 88, 153, 152, 165 }, + { 88, 169, 152, 181 }, + { 88, 185, 152, 197 }, + { 165, 153, 232, 165 }, + { 165, 169, 232, 181 }, + { 165, 185, 233, 197 }, + { 249, 153, 305, 165 }, + { 249, 169, 305, 181 }, + { 249, 185, 305, 197 } +}; + +// Inventory control locations */ +const int INVENTORY_POINTS[8][3] = { + { 4, 50, 28 }, + { 52, 99, 76 }, + { 101, 140, 122 }, + { 142, 187, 165 }, + { 189, 219, 197 }, + { 221, 251, 233 }, + { 253, 283, 265 }, + { 285, 315, 293 } +}; + +/*----------------------------------------------------------------*/ + + void BgFileHeader::synchronize(Common::SeekableReadStream &s) { _numStructs = s.readUint16LE(); _numImages = s.readUint16LE(); @@ -89,7 +121,8 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { _goToRoom = -1; _changes = false; _charPoint = _oldCharPoint = 0; - _windowOpen = _infoFlag = false; + _windowOpen = false; + _infoFlag = false; _keyboardInput = 0; _walkedInScene = false; _ongoingCans = 0; @@ -102,6 +135,10 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { _menuMode = STD_MODE; _invMode = INVMODE_0; _restoreFlag = false; + _invLookFlag = false; + _lookHelp = false; + _animating = 0; + _doBgAnimDone = true; _controlPanel = new ImageFile("controls.vgs"); _controls = nullptr; // new ImageFile("menu.all"); @@ -236,7 +273,7 @@ bool Scene::loadScene(const Common::String &filename) { _bgShapes[idx]._sequences = &_sequenceBuffer[_bgShapes[idx]._sequenceOffset]; _bgShapes[idx]._misc = 0; _bgShapes[idx]._seqCounter = 0; - _bgShapes[idx]._seqcounter2 = 0; + _bgShapes[idx]._seqCounter2 = 0; _bgShapes[idx]._seqStack = 0; _bgShapes[idx]._frameNumber = -1; _bgShapes[idx]._position = Common::Point(0, 0); @@ -799,7 +836,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) { Talk &talk = *_vm->_talk; Common::Point tpPos, walkPos; int tpDir, walkDir; - int tFrames; + int tFrames = 0; int gotoCode = -1; // Validation @@ -996,8 +1033,52 @@ int Scene::startCAnim(int cAnimNum, int playRate) { return 1; } +/** + * Print the description of an object + */ void Scene::printObjDesc(const Common::String &str, bool firstTime) { + /* TODO + + Events &events = *_vm->_events; + Screen &screen = *_vm->_screen; + Talk &talk = *_vm->_talk; + int savedSelector; + + if (str.hasPrefix("_")) { + _lookScriptFlag = true; + events.setCursor(MAGNIFY); + savedSelector = _selector; + talk.talkTo(str.c_str() + 1); + _lookScriptFlag = false; + + if (talk._talkToAbort) { + events.setCursor(ARROW); + return; + } + + // Check if looking at an inventory object + if (!_invLookFlag) { + // See if this look was called by a right button click or not + if (!_lookHelp) { + // If it wasn't a right button click, then we need depress + // the look button before we close the window. So save a copy of the + // menu area, and draw the controls onto it + Surface tempSurface((*_controls)[0]._frame->w, (*_controls)[0]._frame->h); + tempSurface.blitFrom(screen._backBuffer2, Common::Point(0, 0), + Common::Rect(MENU_POINTS[0][0], MENU_POINTS[0][1], + MENU_POINTS[0][0] + tempSurface.w, MENU_POINTS[0][1] + tempSurface.h)); + screen._backBuffer2.transBlitFrom((*_controls)[0]._frame, + Common::Point(MENU_POINTS[0][0], MENU_POINTS[0][1])); + + banishWindow(1); + events.setCursor(MAGNIFY); + + } + } + } + // TODO + */ } /** @@ -1047,9 +1128,270 @@ void Scene::doBgAnim() { if (_restoreFlag) { if (people[AL]._type == CHARACTER) people[AL].checkSprite(); + + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE) + _bgShapes[idx].checkObject(_bgShapes[idx]); + } + + if (people._portraitLoaded && people._portrait._type == ACTIVE_BG_SHAPE) + people._portrait.checkObject(people._portrait); + + for (uint idx = 0; idx < _canimShapes.size(); ++idx) { + if (_canimShapes[idx]._type != INVALID && _canimShapes[idx]._type != REMOVE) + _canimShapes[idx].checkObject(_bgShapes[0]); + } + + if (_currentScene == 12 && _vm->getGameID() == GType_SerratedScalpel) + ((Scalpel::ScalpelEngine *)_vm)->eraseMirror12(); + + // Restore the back buffer from the back buffer 2 in the changed area + Common::Rect bounds(people[AL]._oldPosition.x, people[AL]._oldPosition.y, + people[AL]._oldPosition.x + people[AL]._oldSize.x, + people[AL]._oldPosition.y + people[AL]._oldSize.y); + Common::Point pt(bounds.left, bounds.top); + + if (people[AL]._type == CHARACTER) + screen.restoreBackground(bounds); + else if (people[AL]._type == REMOVE) + screen._backBuffer.blitFrom(screen._backBuffer2, pt, bounds); + + for (uint idx = 0; _bgShapes.size(); ++idx) { + Object &o = _bgShapes[idx]; + if (o._type == ACTIVE_BG_SHAPE || o._type == HIDE_SHAPE || o._type == REMOVE) + screen.restoreBackground(bounds); + } + + if (people._portraitLoaded) + screen.restoreBackground(Common::Rect( + people._portrait._oldPosition.x, people._portrait._oldPosition.y, + people._portrait._oldPosition.x + people._portrait._oldSize.x, + people._portrait._oldPosition.y + people._portrait._oldSize.y + )); + + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + Object &o = _bgShapes[idx]; + if (o._type == NO_SHAPE && ((o._flags & 1) == 0)) { + // Restore screen area + screen._backBuffer.blitFrom(screen._backBuffer2, o._position, + Common::Rect(o._position.x, o._position.y, + o._position.x + o._noShapeSize.x, o._position.y + o._noShapeSize.y)); + + o._oldPosition = o._position; + o._oldSize = o._noShapeSize; + } + } + + for (uint idx = 0; idx < _canimShapes.size(); ++idx) { + Object &o = _canimShapes[idx]; + if (o._type == ACTIVE_BG_SHAPE || o._type == HIDE_SHAPE || o._type == REMOVE) + screen.restoreBackground(Common::Rect(o._oldPosition.x, o._oldPosition.y, + o._oldPosition.x + o._oldSize.x, o._oldPosition.y + o._oldSize.y)); + } + } + + // + // Update the background objects and canimations + // + + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + Object &o = _bgShapes[idx]; + if (o._type == ACTIVE_BG_SHAPE || o._type == NO_SHAPE) + o.adjustObject(); } + for (uint idx = 0; idx < _canimShapes.size(); ++idx) { + if (_canimShapes[idx]._type != INVALID) + _canimShapes[idx].adjustObject(); + } + + if (people[AL]._type == CHARACTER && people._holmesOn) + people[AL].adjustSprite(); + + // Flag the bg shapes which need to be redrawn + checkBgShapes(people[AL]._imageFrame, + Common::Point(people[AL]._position.x / 100, people[AL]._position.y / 100)); + + if (_currentScene == 12 && _vm->getGameID() == GType_SerratedScalpel) + ((Scalpel::ScalpelEngine *)_vm)->doMirror12(); + + // Draw all active shapes which are behind the person + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + Object &o = _bgShapes[idx]; + if (o._type == ACTIVE_BG_SHAPE && o._misc == BEHIND) + screen._backBuffer.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + } + + // Draw all canimations which are behind the person + for (uint idx = 0; idx < _canimShapes.size(); ++idx) { + Object &o = _canimShapes[idx]; + if (o._type == ACTIVE_BG_SHAPE && o._misc == BEHIND) { + screen._backBuffer.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + } + } + + // Draw all active shapes which are HAPPEN and behind the person + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + Object &o = _bgShapes[idx]; + if (o._type == ACTIVE_BG_SHAPE && o._misc == NORMAL_BEHIND) + screen._backBuffer.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + } + + // Draw all canimations which are NORMAL and behind the person + for (uint idx = 0; idx < _canimShapes.size(); ++idx) { + Object &o = _canimShapes[idx]; + if (o._type == ACTIVE_BG_SHAPE && o._misc == NORMAL_BEHIND) { + screen._backBuffer.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + } + } + + // Draw the person if not animating + if (people[AL]._type == CHARACTER && people.isHolmesActive()) { + // If Holmes is too far to the right, move him back so he's on-screen + int xRight = SHERLOCK_SCREEN_WIDTH - 2 - people[AL]._imageFrame->_frame.w; + int tempX = MIN(people[AL]._position.x / 100, xRight); + + bool flipped = people[AL]._frameNumber == WALK_LEFT || people[AL]._frameNumber == STOP_LEFT || + people[AL]._frameNumber == WALK_UPLEFT || people[AL]._frameNumber == STOP_UPLEFT || + people[AL]._frameNumber == WALK_DOWNRIGHT || people[AL]._frameNumber == STOP_DOWNRIGHT; + screen._backBuffer.transBlitFrom(people[AL]._imageFrame->_frame, + Common::Point(tempX, people[AL]._position.y / 100 - people[AL]._imageFrame->_frame.h), flipped); + } + + // Draw all static and active shapes are NORMAL and are in front of the person + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + Object &o = _bgShapes[idx]; + if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == NORMAL_FORWARD) + screen._backBuffer.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + } + + // Draw all static and active canimations that are NORMAL and are in front of the person + for (uint idx = 0; idx < _canimShapes.size(); ++idx) { + Object &o = _canimShapes[idx]; + if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == NORMAL_BEHIND) { + screen._backBuffer.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + } + } + + // Draw all static and active shapes that are in front of the person + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + Object &o = _bgShapes[idx]; + if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == FORWARD) + screen._backBuffer.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + } + + // Draw any active portrait + if (people._portraitLoaded && people._portrait._type == ACTIVE_BG_SHAPE) + screen._backBuffer.transBlitFrom(people._portrait._imageFrame->_frame, + people._portrait._position, people._portrait._flags & 2); + + // Draw all static and active canimations that are in front of the person + for (uint idx = 0; idx < _canimShapes.size(); ++idx) { + Object &o = _canimShapes[idx]; + if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == FORWARD) { + screen._backBuffer.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + } + } + + // Draw all NO_SHAPE shapes which have flag bit 0 clear + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + Object &o = _bgShapes[idx]; + if (o._type == NO_SHAPE && (o._flags & 1) == 0) + screen._backBuffer.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + } + + // Bring the newly built picture to the screen + if (_animating == 2) { + _animating = 0; + screen.slamRect(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); + } else { + if (people[AL]._type != INVALID && ((_goToRoom == -1 || _ongoingCans == 0))) { + if (people[AL]._type == REMOVE) { + screen.slamRect(Common::Rect( + people[AL]._oldPosition.x, people[AL]._oldPosition.y, + people[AL]._oldPosition.x + people[AL]._oldSize.x, + people[AL]._oldPosition.y + people[AL]._oldSize.y + )); + } else { + screen.flushImage(people[AL]._imageFrame, + Common::Point(people[AL]._position.x / 100, people[AL]._position.y / 100), + &people[AL]._oldPosition.x, &people[AL]._oldPosition.y, + &people[AL]._oldSize.x, &people[AL]._oldSize.y); + } + } + + if (_currentScene == 12 && _vm->getGameID() == GType_SerratedScalpel) + ((Scalpel::ScalpelEngine *)_vm)->flushMirror12(); + + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + Object &o = _bgShapes[idx]; + if ((o._type == ACTIVE_BG_SHAPE || o._type == REMOVE) && _goToRoom == -1) { + screen.flushImage(o._imageFrame, o._position, + &o._oldPosition.x, &o._oldPosition.y, &o._oldSize.x, &o._oldSize.y); + } + } + + if (people._portraitLoaded) { + if (people._portrait._type == REMOVE) + screen.slamRect(Common::Rect( + people._portrait._position.x, people._portrait._position.y, + people._portrait._position.x + people._portrait._delta.x, + people._portrait._position.y + people._portrait._delta.y + )); + else + screen.flushImage(people._portrait._imageFrame, people._portrait._position, + &people._portrait._oldPosition.x, &people._portrait._oldPosition.y, + &people._portrait._oldSize.x, &people._portrait._oldSize.y); + + if (people._portrait._type == REMOVE) + people._portrait._type = INVALID; + } + + if (_goToRoom == -1) { + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + Object &o = _bgShapes[idx]; + if (o._type == NO_SHAPE && (o._flags & 1) == 0) { + screen.slamArea(o._position.x, o._position.y, o._oldSize.x, o._oldSize.y); + screen.slamArea(o._oldPosition.x, o._oldPosition.y, o._oldSize.x, o._oldSize.y); + } else if (o._type == HIDE_SHAPE) { + screen.flushImage(o._imageFrame, o._position, + &o._oldPosition.x, &o._oldPosition.y, &o._oldSize.x, &o._oldSize.y); + } + } + } + + for (int idx = _canimShapes.size() - 1; idx >= 0; --idx) { + Object &o = _canimShapes[idx]; + if (o._type == REMOVE) { + if (_goToRoom == -1) + screen.slamArea(o._position.x, o._position.y, o._delta.x, o._delta.y); + + _canimShapes.remove_at(idx); + } else if (o._type == ACTIVE_BG_SHAPE) { + screen.flushImage(o._imageFrame, o._position, + &o._oldPosition.x, &o._oldPosition.y, &o._oldSize.x, &o._oldSize.y); + } + } + } + + _restoreFlag = true; + + events.wait(1); + _doBgAnimDone = true; + + // Check if the method was called for calling a portrait, and a talk was + // interrupting it. This talk file would not have been executed at the time, + // since we needed to finish the 'doBgAnim' to finish clearing the portrait + if (people._clearingThePortrait && _vm->_scriptMoreFlag == 3) { + // Reset the flags and call to talk + people._clearingThePortrait = _vm->_scriptMoreFlag = 0; + talk.talkTo(_vm->_scriptName); + } +} + +void Scene::clearInfo() { // TODO } + } // End of namespace Sherlock diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index f48d45c34e..4b76739402 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -116,6 +116,10 @@ private: Common::String _cAnimStr; MenuMode _menuMode; InvMode _invMode; + bool _lookScriptFlag; + int _selector; + bool _invLookFlag; + bool _lookHelp; bool loadScene(const Common::String &filename); @@ -125,15 +129,9 @@ private: void transitionToScene(); - int toggleObject(const Common::String &name); - void updateBackground(); void checkBgShapes(ImageFrame *frame, const Common::Point &pt); - - int startCAnim(int cAnimNum, int playRate); - - void doBgAnim(); public: int _currentScene; int _goToRoom; @@ -170,6 +168,8 @@ public: int _hsavedFs; Common::Array _canimShapes; bool _restoreFlag; + int _animating; + bool _doBgAnimDone; public: Scene(SherlockEngine *vm); ~Scene(); @@ -183,6 +183,14 @@ public: Exit *checkForExit(const Common::Rect &r); void printObjDesc(const Common::String &str, bool firstTime); + + int startCAnim(int cAnimNum, int playRate); + + int toggleObject(const Common::String &name); + + void doBgAnim(); + + void clearInfo(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index e6c11b8cf4..f8f1d56e67 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -231,4 +231,67 @@ void Screen::verticalTransition() { } } +/** + * Prints the text passed onto the back buffer at the given position and color. + * The string is then blitted to the screen + */ +void Screen::print(const Common::Point &pt, int fgColor, int bgColor, const char *format, ...) { + // TODO +} + +/** + * Copies a section of the second back buffer into the main back buffer + */ +void Screen::restoreBackground(const Common::Rect &r) { + Common::Rect tempRect = r; + tempRect.clip(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); + + if (tempRect.isValidRect()) + _backBuffer.blitFrom(_backBuffer2, Common::Point(tempRect.left, tempRect.top), tempRect); +} + +/** + * Copies a given area to the screen + */ +void Screen::slamArea(int16 xp, int16 yp, int16 w, int16 h) { + slamRect(Common::Rect(xp, yp, xp + w, yp + h)); +} + +/** + * Copies a given area to the screen + */ +void Screen::slamRect(const Common::Rect &r) { + Common::Rect tempRect = r; + tempRect.clip(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + + if (tempRect.isValidRect()) + blitFrom(_backBuffer, Common::Point(tempRect.left, tempRect.top), tempRect); +} + +/** + * Copy an image from the back buffer to the screen, taking care of both the + * new area covered by the shape as well as the old area, which must be restored + */ +void Screen::flushImage(ImageFrame *frame, const Common::Point &pt, + int16 *xp, int16 *yp, int16 *w, int16 *h) { + Common::Point imgPos = pt + frame->_offset; + Common::Rect newBounds(imgPos.x, imgPos.y, imgPos.x + frame->_frame.w, imgPos.y + frame->_frame.h); + Common::Rect oldBounds(*xp, *yp, *xp + *w, *yp + *h); + + // See if the areas of the old and new overlap, and if so combine the areas + if (newBounds.intersects(oldBounds)) { + newBounds.extend(oldBounds); + slamRect(newBounds); + } else { + // The two areas are independent, so copy them both + slamRect(newBounds); + slamRect(oldBounds); + } + + *xp = newBounds.left; + *yp = newBounds.top; + *w = newBounds.width(); + *h = newBounds.height(); +} + } // End of namespace Sherlock diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 2c5e585475..87453ba36d 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -26,8 +26,8 @@ #include "common/list.h" #include "common/rect.h" #include "graphics/surface.h" - #include "sherlock/graphics.h" +#include "sherlock/resources.h" namespace Sherlock { @@ -75,6 +75,16 @@ public: void randomTransition(); void verticalTransition(); + + void print(const Common::Point &pt, int fgColor, int bgColor, const char *format, ...); + + void restoreBackground(const Common::Rect &r); + + void slamArea(int16 xp, int16 yp, int16 w, int16 h); + void slamRect(const Common::Rect &r); + + void flushImage(ImageFrame *frame, const Common::Point &pt, + int16 *xp, int16 *yp, int16 *w, int16 *h); }; } // End of namespace Sherlock diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 637660e001..330da6075b 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -45,7 +45,8 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _justLoaded = false; _onChessboard = false; _slowChess = false; - _animating = false; + _menuCounter = 0; + _scriptMoreFlag = 0; } SherlockEngine::~SherlockEngine() { diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 1c95b10ff3..92aee9cdc3 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -98,7 +98,9 @@ public: Common::Array _map; // Map locations for each scene bool _onChessboard; bool _slowChess; - bool _animating; + int _menuCounter; + int _scriptMoreFlag; + Common::String _scriptName; public: SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc); virtual ~SherlockEngine(); -- cgit v1.2.3 From 3c77a521dc07a8c0954b11b26dda382817776b9e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 22 Mar 2015 09:02:31 -0400 Subject: SHERLOCK: Implement main scene loop and more inventory code --- engines/sherlock/debugger.cpp | 2 +- engines/sherlock/graphics.cpp | 7 ++- engines/sherlock/graphics.h | 1 + engines/sherlock/inventory.cpp | 92 ++++++++++++++++++++++++++++++++++++ engines/sherlock/inventory.h | 24 +++++++++- engines/sherlock/objects.cpp | 12 ++--- engines/sherlock/people.cpp | 15 ++++++ engines/sherlock/people.h | 2 + engines/sherlock/scalpel/scalpel.cpp | 31 ++++++------ engines/sherlock/scalpel/scalpel.h | 1 - engines/sherlock/scene.cpp | 72 ++++++++++++++++++++++------ engines/sherlock/scene.h | 6 ++- engines/sherlock/sherlock.cpp | 34 +++++++++++-- engines/sherlock/sherlock.h | 3 ++ engines/sherlock/talk.cpp | 8 ++++ engines/sherlock/talk.h | 4 +- 16 files changed, 267 insertions(+), 47 deletions(-) diff --git a/engines/sherlock/debugger.cpp b/engines/sherlock/debugger.cpp index 1e0716c3d3..b8ac8bef6a 100644 --- a/engines/sherlock/debugger.cpp +++ b/engines/sherlock/debugger.cpp @@ -51,7 +51,7 @@ bool Debugger::cmd_scene(int argc, const char **argv) { debugPrintf("Format: scene \n"); return true; } else { - _vm->_scene->_goToRoom = strToInt(argv[1]); + _vm->_scene->_goToScene = strToInt(argv[1]); return false; } } diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index 8c096e3c72..63988a2f30 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -145,7 +145,12 @@ void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &p * Fill a given area of the surface with a given color */ void Surface::fillRect(int x1, int y1, int x2, int y2, byte color) { - Graphics::Surface::fillRect(Common::Rect(x1, y1, x2, y2), color); + fillRect(Common::Rect(x1, y1, x2, y2), color); +} + +void Surface::fillRect(const Common::Rect &r, byte color) { + Graphics::Surface::fillRect(r, color); + addDirtyRect(r); } /** diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index 0536c016bf..b33495a2b9 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -47,6 +47,7 @@ public: bool flipped = false, int overrideColor = 0); void fillRect(int x1, int y1, int x2, int y2, byte color); + void fillRect(const Common::Rect &r, byte color); Surface getSubArea(const Common::Rect &r); }; diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index 634e664f5a..cbb69f1041 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -21,7 +21,99 @@ */ #include "sherlock/inventory.h" +#include "sherlock/sherlock.h" namespace Sherlock { +Inventory::Inventory(SherlockEngine *vm) : Common::Array(), _vm(vm) { + Common::fill(&_invShapes[0], &_invShapes[MAX_VISIBLE_INVENTORY], (ImageFile *)nullptr); + _invGraphicsLoaded = false; + _invIndex = 0; + _holdings = 0; +} + +Inventory::~Inventory() { + freeGraphics(); +} + +void Inventory::freeInventory() { + freeGraphics(); + + _names.clear(); + _invGraphicsLoaded = false; +} + +/** + * Free any loaded inventory graphics + */ +void Inventory::freeGraphics() { + for (uint idx = 0; idx < MAX_VISIBLE_INVENTORY; ++idx) + delete _invShapes[idx]; + + Common::fill(&_invShapes[0], &_invShapes[MAX_VISIBLE_INVENTORY], (ImageFile *)nullptr); + _invGraphicsLoaded = false; +} + +/** Load the list of names the inventory items correspond to. + */ +void Inventory::loadInv() { + // Exit if the inventory names are already loaded + if (_names.size() > 0) + return; + + // Load the inventory names + Common::SeekableReadStream *stream = _vm->_res->load("invent.txt"); + _names.clear(); + + while (stream->pos() < stream->size()) { + Common::String name; + char c; + while ((c = stream->readByte()) != 0) + name += c; + + _names.push_back(name); + } + + delete stream; +} + +/** + * Load the list of names of graphics for the inventory + */ +void Inventory::loadGraphics() { + if (_invGraphicsLoaded) + return; + + // Default all inventory slots to empty + Common::fill(&_invShapes[0], &_invShapes[MAX_VISIBLE_INVENTORY], (ImageFile *)nullptr); + + for (int idx = _invIndex; (idx < _holdings) && (idx - _invIndex) < 6; ++idx) { + // Get the name of the item to be dispalyed, figure out it's accompanying + // .VGS file with it's picture, and then load it + int invNum = findInv((*this)[idx]._name); + Common::String fName = Common::String::format("item%02d.vgs", invNum); + + _invShapes[idx] = new ImageFile(fName); + } + + _invGraphicsLoaded = true; +} + +/** + * Searches through the list of names that correspond to the inventory items + * and returns the numer that matches the passed name + */ +int Inventory::findInv(const Common::String &name) { + int result = -1; + + for (uint idx = 0; (idx < _holdings) && result == -1; ++idx) { + if (scumm_stricmp(name.c_str(), _names[idx].c_str()) == 0) + result = idx; + } + + if (result == -1) + result = 1; + return result; +} + } // End of namespace Sherlock diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index dc56e93841..e561f0318a 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -25,9 +25,13 @@ #include "common/scummsys.h" #include "common/array.h" +#include "common/str-array.h" +#include "sherlock/resources.h" namespace Sherlock { +#define MAX_VISIBLE_INVENTORY 6 + struct InventoryItem { int _requiredFlag; Common::String _name; @@ -37,10 +41,26 @@ struct InventoryItem { }; class Inventory : public Common::Array { +private: + SherlockEngine *_vm; +public: + ImageFile *_invShapes[MAX_VISIBLE_INVENTORY]; + Common::StringArray _names; + bool _invGraphicsLoaded; + int _invIndex; + int _holdings; + void freeGraphics(); public: - uint _holdings; + Inventory(SherlockEngine *vm); + ~Inventory(); + + void freeInventory(); + + void loadInv(); + + void loadGraphics(); - Inventory() : Common::Array(), _holdings(0) {} + int findInv(const Common::String &name); }; } // End of namespace Sherlock diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 6b681b42e9..1643bef7b0 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -159,7 +159,7 @@ void Sprite::adjustSprite() { setImageFrame(); // Check to see if character has entered an exit zone - if (!_walkCount && scene._walkedInScene && scene._goToRoom == -1) { + if (!_walkCount && scene._walkedInScene && scene._goToScene == -1) { Common::Rect charRect(_position.x / 100 - 5, _position.y / 100 - 2, _position.x / 100 + 5, _position.y / 100 + 2); Exit *exit = scene.checkForExit(charRect); @@ -819,11 +819,11 @@ int Object::checkNameForCodes(const Common::String &name, Common::StringArray *m default: if (ch >= '0' && ch <= '9') { - scene._goToRoom = atoi(name.c_str() + 1); + scene._goToScene = atoi(name.c_str() + 1); - if (scene._goToRoom < 97 && _vm->_map[scene._goToRoom].x) { - _vm->_over.x = _vm->_map[scene._goToRoom].x * 100 - 600; - _vm->_over.y = _vm->_map[scene._goToRoom].y * 100 + 900; + if (scene._goToScene < 97 && _vm->_map[scene._goToScene].x) { + _vm->_over.x = _vm->_map[scene._goToScene].x * 100 - 600; + _vm->_over.y = _vm->_map[scene._goToScene].y * 100 + 900; } if ((p = strchr(name.c_str(), ',')) != nullptr) { @@ -844,7 +844,7 @@ int Object::checkNameForCodes(const Common::String &name, Common::StringArray *m scene._hsavedFs = 100 + atoi(p + 1); } } else { - scene._goToRoom = 100; + scene._goToScene = 100; } people[AL]._position = Common::Point(0, 0); diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index d2fbb3d8c5..91689e296c 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -99,6 +99,21 @@ bool People::loadWalk() { } } +/** + * If the walk data has been loaded, then it will be freed + */ +bool People::freeWalk() { + if (_walkLoaded) { + delete _player._images; + _player._images = nullptr; + + _walkLoaded = false; + return true; + } else { + return false; + } +} + /** * Set the variables for moving a character from one poisition to another * in a straight line - goAllTheWay must have been previously called to diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index 7c218671c9..de84675e66 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -79,6 +79,8 @@ public: bool loadWalk(); + bool freeWalk(); + void setWalking(); void gotoStand(Sprite &sprite); diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 1fe1901212..3ec971895a 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -43,7 +43,6 @@ ScalpelEngine::ScalpelEngine(OSystem *syst, const SherlockGameDescription *gameD SherlockEngine(syst, gameDesc) { _chess = nullptr; _darts = nullptr; - _tempFadeStyle = 0; _chessResult = 0; } @@ -70,7 +69,7 @@ void ScalpelEngine::initialize() { _map.push_back(Common::Point(MAP_X[idx], MAP_Y[idx])); // Starting scene - _scene->_goToRoom = 4; + _scene->_goToScene = 4; } /** @@ -181,7 +180,7 @@ bool ScalpelEngine::showOfficeCutscene() { * Starting a scene within the game */ void ScalpelEngine::startScene() { - if (_scene->_goToRoom == 100 || _scene->_goToRoom == 98) { + if (_scene->_goToScene == 100 || _scene->_goToScene == 98) { // Chessboard selection if (_sound->_musicOn) { if (_sound->loadSong(100)) { @@ -190,7 +189,7 @@ void ScalpelEngine::startScene() { } } - _scene->_goToRoom = _chess->doChessBoard(); + _scene->_goToScene = _chess->doChessBoard(); _sound->freeSong(); _scene->_hsavedPos = Common::Point(-1, -1); @@ -203,17 +202,17 @@ void ScalpelEngine::startScene() { // 53: Moorehead's death / subway train // 55: Fade out and exit // 70: Brumwell suicide - switch (_scene->_goToRoom) { + switch (_scene->_goToScene) { case 2: case 52: case 53: case 70: - if (_sound->_musicOn && _sound->loadSong(_scene->_goToRoom)) { + if (_sound->_musicOn && _sound->loadSong(_scene->_goToScene)) { if (_sound->_music) _sound->startSong(); } - switch (_scene->_goToRoom) { + switch (_scene->_goToScene) { case 2: // Blackwood's capture _res->addToCache("final2.vda", "epilogue.lib"); @@ -269,7 +268,7 @@ void ScalpelEngine::startScene() { _animation->playPrologue("SUBWAY3", 1, 0, false, 4); // Set fading to direct fade temporary so the transition goes quickly. - _tempFadeStyle = _screen->_fadeStyle ? 257 : 256; + _scene->_tempFadeStyle = _screen->_fadeStyle ? 257 : 256; _screen->_fadeStyle = false; break; @@ -282,28 +281,28 @@ void ScalpelEngine::startScene() { } // Except for the Moorehead Murder scene, fade to black first - if (_scene->_goToRoom != 53) { + if (_scene->_goToScene != 53) { _events->wait(40); _screen->fadeToBlack(3); } - switch (_scene->_goToRoom) { + switch (_scene->_goToScene) { case 52: - _scene->_goToRoom = 27; // Go to the Lawyer's Office + _scene->_goToScene = 27; // Go to the Lawyer's Office _scene->_bigPos = Common::Point(0, 0); // Overland scroll position _scene->_overPos = Common::Point(22900 - 600, 9400 + 900); // Overland position _scene->_oldCharPoint = 27; break; case 53: - _scene->_goToRoom = 17; // Go to St. Pancras Station + _scene->_goToScene = 17; // Go to St. Pancras Station _scene->_bigPos = Common::Point(0, 0); // Overland scroll position _scene->_overPos = Common::Point(32500 - 600, 3000 + 900); // Overland position _scene->_oldCharPoint = 17; break; default: - _scene->_goToRoom = 4; // Back to Baker st. + _scene->_goToScene = 4; // Back to Baker st. _scene->_bigPos = Common::Point(0, 0); // Overland scroll position _scene->_overPos = Common::Point(14500 - 600, 8400 + 900); // Overland position _scene->_oldCharPoint = 4; @@ -327,13 +326,13 @@ void ScalpelEngine::startScene() { _events->loadCursors("rmouse.vgs"); _events->setCursor(ARROW); - if (_scene->_goToRoom == 99) { + if (_scene->_goToScene == 99) { // Chess Board _darts->playDarts(); - _chessResult = _scene->_goToRoom = 19; // Go back to the bar + _chessResult = _scene->_goToScene = 19; // Go back to the bar } - _chessResult = _scene->_goToRoom; + _chessResult = _scene->_goToScene; } /** diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h index 2d5deeb882..caf33052aa 100644 --- a/engines/sherlock/scalpel/scalpel.h +++ b/engines/sherlock/scalpel/scalpel.h @@ -35,7 +35,6 @@ class ScalpelEngine : public SherlockEngine { private: Chess *_chess; Darts *_darts; - int _tempFadeStyle; int _chessResult; bool showCityCutscene(); diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 92a8757fd8..e0b5dc1711 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -118,7 +118,7 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { for (int idx = 0; idx < SCENES_COUNT; ++idx) Common::fill(&_stats[idx][0], &_stats[idx][9], false); _currentScene = -1; - _goToRoom = -1; + _goToScene = -1; _changes = false; _charPoint = _oldCharPoint = 0; _windowOpen = false; @@ -139,6 +139,8 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { _lookHelp = false; _animating = 0; _doBgAnimDone = true; + _oldLook = 0; + _tempFadeStyle = 0; _controlPanel = new ImageFile("controls.vgs"); _controls = nullptr; // new ImageFile("menu.all"); @@ -156,7 +158,14 @@ Scene::~Scene() { void Scene::clear() { } +/** + * Handles loading the scene specified by _goToScene + */ void Scene::selectScene() { + Events &events = *_vm->_events; + People &people = *_vm->_people; + Screen &screen = *_vm->_screen; + // Reset fields _windowOpen = _infoFlag = false; _menuMode = STD_MODE; @@ -165,12 +174,39 @@ void Scene::selectScene() { _oldTemp = _temp = 0; // Load the scene - Common::String sceneFile = Common::String::format("res%02d", _goToRoom); - _rrmName = Common::String::format("res%02d.rrm", _goToRoom); - _currentScene = _goToRoom; - _goToRoom = -1; + Common::String sceneFile = Common::String::format("res%02d", _goToScene); + _rrmName = Common::String::format("res%02d.rrm", _goToScene); + _currentScene = _goToScene; + _goToScene = -1; loadScene(sceneFile); + + // If the fade style was changed from running amovie, then reset it + if (_tempFadeStyle) { + screen._fadeStyle = _tempFadeStyle; + _tempFadeStyle = 0; + } + + people._walkDest = Common::Point(people[AL]._position.x / 100, + people[AL]._position.y / 100); + + _restoreFlag = true; + events.clearEvents(); + + // If there were any scripst waiting to be run, but were interrupt by a running + // canimation (probably the last scene's exit canim), clear the _scriptMoreFlag + if (_vm->_scriptMoreFlag == 3) + _vm->_scriptMoreFlag = 0; +} + +/** + * Fres all the graphics and other dynamically allocated data for the scene + */ +void Scene::freeScene() { + _vm->_inventory->freeInventory(); + + _roomBounds.clear(); + _canimShapes.clear(); } /** @@ -506,7 +542,7 @@ void Scene::checkSceneFlags(bool flag) { } // Check inventory - for (uint idx = 0; idx < _vm->_inventory->_holdings; ++idx) { + for (int idx = 0; idx < _vm->_inventory->_holdings; ++idx) { InventoryItem &ii = (*_vm->_inventory)[idx]; if (ii._requiredFlag && !_vm->readFlags(ii._requiredFlag)) { // Kill object: move it after the active holdings @@ -1013,10 +1049,10 @@ int Scene::startCAnim(int cAnimNum, int playRate) { cObj.checkObject(_bgShapes[0]); if (gotoCode > 0 && !talk._talkToAbort) { - _goToRoom = gotoCode; + _goToScene = gotoCode; - if (_goToRoom < 97 && _vm->_map[_goToRoom].x) { - _overPos = _vm->_map[_goToRoom]; + if (_goToScene < 97 && _vm->_map[_goToScene].x) { + _overPos = _vm->_map[_goToScene]; } } @@ -1305,7 +1341,7 @@ void Scene::doBgAnim() { _animating = 0; screen.slamRect(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); } else { - if (people[AL]._type != INVALID && ((_goToRoom == -1 || _ongoingCans == 0))) { + if (people[AL]._type != INVALID && ((_goToScene == -1 || _ongoingCans == 0))) { if (people[AL]._type == REMOVE) { screen.slamRect(Common::Rect( people[AL]._oldPosition.x, people[AL]._oldPosition.y, @@ -1325,7 +1361,7 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; - if ((o._type == ACTIVE_BG_SHAPE || o._type == REMOVE) && _goToRoom == -1) { + if ((o._type == ACTIVE_BG_SHAPE || o._type == REMOVE) && _goToScene == -1) { screen.flushImage(o._imageFrame, o._position, &o._oldPosition.x, &o._oldPosition.y, &o._oldSize.x, &o._oldSize.y); } @@ -1347,7 +1383,7 @@ void Scene::doBgAnim() { people._portrait._type = INVALID; } - if (_goToRoom == -1) { + if (_goToScene == -1) { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if (o._type == NO_SHAPE && (o._flags & 1) == 0) { @@ -1363,7 +1399,7 @@ void Scene::doBgAnim() { for (int idx = _canimShapes.size() - 1; idx >= 0; --idx) { Object &o = _canimShapes[idx]; if (o._type == REMOVE) { - if (_goToRoom == -1) + if (_goToScene == -1) screen.slamArea(o._position.x, o._position.y, o._delta.x, o._delta.y); _canimShapes.remove_at(idx); @@ -1389,8 +1425,16 @@ void Scene::doBgAnim() { } } +/** + * Clears the info line of the screen + */ void Scene::clearInfo() { - // TODO + if (_infoFlag) { + _vm->_screen->fillRect(16, INFO_LINE, SHERLOCK_SCREEN_WIDTH - 200, INFO_LINE + 9, + INFO_BLACK); + _infoFlag = false; + _oldLook = -1; + } } diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 4b76739402..25c97c097a 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -120,6 +120,7 @@ private: int _selector; bool _invLookFlag; bool _lookHelp; + int _oldLook; bool loadScene(const Common::String &filename); @@ -134,7 +135,7 @@ private: void checkBgShapes(ImageFrame *frame, const Common::Point &pt); public: int _currentScene; - int _goToRoom; + int _goToScene; bool _changes; bool _stats[SCENES_COUNT][9]; bool _savedStats[SCENES_COUNT][9]; @@ -170,6 +171,7 @@ public: bool _restoreFlag; int _animating; bool _doBgAnimDone; + int _tempFadeStyle; public: Scene(SherlockEngine *vm); ~Scene(); @@ -178,6 +180,8 @@ public: void selectScene(); + void freeScene(); + void checkSceneFlags(bool mode); Exit *checkForExit(const Common::Rect &r); diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 330da6075b..e023bf9b16 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -75,7 +75,7 @@ void SherlockEngine::initialize() { _animation = new Animation(this); _debugger = new Debugger(this); _events = new Events(this); - _inventory = new Inventory(); + _inventory = new Inventory(this); _journal = new Journal(); _people = new People(this); _scene = new Scene(this); @@ -102,14 +102,40 @@ Common::Error SherlockEngine::run() { // Initialize and load the scene. _scene->selectScene(); - // TODO: Implement game and remove this dummy loop - while (!shouldQuit()) - _events->pollEventsAndWait(); + // Scene handling loop + sceneLoop(); } return Common::kNoError; } +void SherlockEngine::sceneLoop() { + while (!shouldQuit() && _scene->_goToScene != -1) { + // See if a script needs to be completed from either a goto room code, + // or a script that was interrupted by another script + if (_scriptMoreFlag == 1 || _scriptMoreFlag == 3) + _talk->talkTo(_scriptName); + else + _scriptMoreFlag = 0; + + // Handle any input from the keyboard or mouse + handleInput(); + + if (_scene->_hsavedPos.x == -1) + _scene->doBgAnim(); + } + + _scene->freeScene(); + _talk->freeTalkVars(); + _people->freeWalk(); + +} + +void SherlockEngine::handleInput() { + // TODO +} + + /** * Read the state of a global flag */ diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 92aee9cdc3..11bea9bdcd 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -68,6 +68,9 @@ class Resource; class SherlockEngine : public Engine { private: + void sceneLoop(); + + void handleInput(); protected: virtual void initialize(); diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 414f3b90a6..4c10b7b7ef 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -34,4 +34,12 @@ void Talk::talkTo(const Common::String &name) { // TODO } +/** + * Clear loaded talk data + */ +void Talk::freeTalkVars() { + _statements.clear(); +} + + } // End of namespace Sherlock diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index 55a4c0fd69..fc73994cc6 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -43,13 +43,15 @@ class Talk { private: SherlockEngine *_vm; public: - Common::Array _history; + Common::Array _statements; bool _talkToAbort; int _talkCounter; public: Talk(SherlockEngine *vm); void talkTo(const Common::String &name); + + void freeTalkVars(); }; } // End of namespace Sherlock -- cgit v1.2.3 From e444d989bb3470650020cb2c3f0fdb7b2fcab70a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 22 Mar 2015 09:51:37 -0400 Subject: SHERLOCK: Implemented scene freeing code --- engines/sherlock/inventory.cpp | 2 +- engines/sherlock/objects.cpp | 2 +- engines/sherlock/objects.h | 4 ++-- engines/sherlock/scene.cpp | 42 ++++++++++++++++++++++++++++-------------- engines/sherlock/scene.h | 6 +++--- engines/sherlock/sherlock.cpp | 2 +- engines/sherlock/sherlock.h | 1 + engines/sherlock/sound.cpp | 4 ++++ engines/sherlock/sound.h | 1 + 9 files changed, 42 insertions(+), 22 deletions(-) diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index cbb69f1041..2a277a6331 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -106,7 +106,7 @@ void Inventory::loadGraphics() { int Inventory::findInv(const Common::String &name) { int result = -1; - for (uint idx = 0; (idx < _holdings) && result == -1; ++idx) { + for (int idx = 0; (idx < _holdings) && result == -1; ++idx) { if (scumm_stricmp(name.c_str(), _names[idx].c_str()) == 0) result = idx; } diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 1643bef7b0..bbe2c9d4d2 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -946,7 +946,7 @@ void CAnim::synchronize(Common::SeekableReadStream &s) { /*----------------------------------------------------------------*/ -InvGraphicType::InvGraphicType() { +SceneImage::SceneImage() { _images = nullptr; _maxFrames = 0; _filesize = 0; diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index ee82faf99c..2ac2e16da0 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -223,12 +223,12 @@ struct CAnim { void synchronize(Common::SeekableReadStream &s); }; -struct InvGraphicType { +struct SceneImage { ImageFile *_images; // Object images int _maxFrames; // How many frames in object int _filesize; // File size - InvGraphicType(); + SceneImage(); } ; } // End of namespace Sherlock diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index e0b5dc1711..18ccdd4050 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -149,13 +149,7 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { Scene::~Scene() { delete _controlPanel; delete _controls; - clear(); -} - -/** - * Takes care of clearing any scene data - */ -void Scene::clear() { + freeScene(); } /** @@ -203,10 +197,27 @@ void Scene::selectScene() { * Fres all the graphics and other dynamically allocated data for the scene */ void Scene::freeScene() { + _vm->_talk->freeTalkVars(); _vm->_inventory->freeInventory(); + _vm->_sound->freeSong(); + _vm->_sound->freeLoadedSounds(); + if (!_vm->_loadingSavedGame) + saveSceneStatus(); + else + _vm->_loadingSavedGame = false; + + _sequenceBuffer.clear(); + _descText.clear(); + _walkData.clear(); + _cAnim.clear(); + _bgShapes.clear(); _roomBounds.clear(); _canimShapes.clear(); + + for (uint idx = 0; idx < _images.size(); ++idx) + delete _images[idx]._images; + _images.clear(); } /** @@ -225,6 +236,7 @@ bool Scene::loadScene(const Common::String &filename) { Sound &sound = *_vm->_sound; bool flag; + freeScene(); _walkedInScene = false; _ongoingCans = 0; @@ -232,7 +244,6 @@ bool Scene::loadScene(const Common::String &filename) { _roomBounds.clear(); _roomBounds.push_back(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); - clear(); _descText.clear(); _comments = ""; _bgShapes.clear(); @@ -287,17 +298,17 @@ bool Scene::loadScene(const Common::String &filename) { if (_lzwMode) delete infoStream; - // Set up inv list - _inv.resize(bgHeader._numImages + 1); + // Set up the list of images used by the scene + _images.resize(bgHeader._numImages + 1); for (int idx = 0; idx < bgHeader._numImages; ++idx) { - _inv[idx + 1]._filesize = bgInfo[idx]._filesize; - _inv[idx + 1]._maxFrames = bgInfo[idx]._maxFrames; + _images[idx + 1]._filesize = bgInfo[idx]._filesize; + _images[idx + 1]._maxFrames = bgInfo[idx]._maxFrames; // Read in the image data Common::SeekableReadStream *imageStream = !_lzwMode ? rrmStream : decompressLZ(*rrmStream, bgInfo[idx]._filesize); - _inv[idx + 1]._images = new ImageFile(*imageStream); + _images[idx + 1]._images = new ImageFile(*imageStream); if (_lzwMode) delete imageStream; @@ -315,7 +326,7 @@ bool Scene::loadScene(const Common::String &filename) { _bgShapes[idx]._position = Common::Point(0, 0); _bgShapes[idx]._oldSize = Common::Point(1, 1); - _bgShapes[idx]._images = _inv[_bgShapes[idx]._misc]._images; + _bgShapes[idx]._images = _images[_bgShapes[idx]._misc]._images; _bgShapes[idx]._imageFrame = !_bgShapes[idx]._images ? (ImageFrame *)nullptr : &(*_bgShapes[idx]._images)[0]; } @@ -1437,5 +1448,8 @@ void Scene::clearInfo() { } } +void Scene::saveSceneStatus() { + // TODO +} } // End of namespace Sherlock diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 25c97c097a..3cdb20ac0f 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -133,6 +133,8 @@ private: void updateBackground(); void checkBgShapes(ImageFrame *frame, const Common::Point &pt); + + void saveSceneStatus(); public: int _currentScene; int _goToScene; @@ -159,7 +161,7 @@ public: Common::Array _bgShapes; Common::Array _cAnim; Common::Array _sequenceBuffer; - Common::Array _inv; + Common::Array _images; int _walkDirectory[MAX_ZONES][MAX_ZONES]; Common::Array _walkData; Common::Array _exits; @@ -176,8 +178,6 @@ public: Scene(SherlockEngine *vm); ~Scene(); - void clear(); - void selectScene(); void freeScene(); diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index e023bf9b16..ad590e3ffd 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -43,6 +43,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _talk = nullptr; _useEpilogue2 = false; _justLoaded = false; + _loadingSavedGame = false; _onChessboard = false; _slowChess = false; _menuCounter = 0; @@ -126,7 +127,6 @@ void SherlockEngine::sceneLoop() { } _scene->freeScene(); - _talk->freeTalkVars(); _people->freeWalk(); } diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 11bea9bdcd..b84f6d7429 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -96,6 +96,7 @@ public: Common::String _titleOverride; bool _useEpilogue2; bool _justLoaded; + bool _loadingSavedGame; int _oldCharPoint; // Old scene Common::Point _over; // Old map position Common::Array _map; // Map locations for each scene diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index e8e433fa84..5e7df5607f 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -56,6 +56,10 @@ void Sound::playCachedSound(int index) { // TODO } +void Sound::freeLoadedSounds() { + // TODO +} + void Sound::clearCache() { // TODO } diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index 3f32f2724a..74e8db3611 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -55,6 +55,7 @@ public: void cacheSound(const Common::String &name, int index); void playLoadedSound(int bufNum, int waitMode); void playCachedSound(int index); + void freeLoadedSounds(); void clearCache(); void stopSound(); int loadSong(int songNumber); -- cgit v1.2.3 From 840bd862b734d54b18eb505b32ce030da10c934d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 22 Mar 2015 10:48:28 -0400 Subject: SHERLOCK: Implement ImageFile nibble mode, fixes for scene data loading --- engines/sherlock/objects.cpp | 11 +++++----- engines/sherlock/objects.h | 2 +- engines/sherlock/resources.cpp | 13 +++++++---- engines/sherlock/resources.h | 2 +- engines/sherlock/scene.cpp | 49 ++++++++++++++++++++---------------------- engines/sherlock/scene.h | 2 +- 6 files changed, 40 insertions(+), 39 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index bbe2c9d4d2..7d86c45e15 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -408,12 +408,11 @@ void Object::setVm(SherlockEngine *vm) { * Load the object data from the passed stream */ void Object::synchronize(Common::SeekableReadStream &s) { - char buffer[50]; - + char buffer[12]; s.read(buffer, 12); _name = Common::String(buffer); - s.read(buffer, 41); - _description = Common::String(buffer); + + s.read(_description, 41); _examine.clear(); _sequences = nullptr; @@ -421,8 +420,8 @@ void Object::synchronize(Common::SeekableReadStream &s) { _imageFrame = nullptr; s.skip(4); - _sequenceOffset = s.readUint32LE(); - s.seek(8, SEEK_CUR); + _sequenceOffset = s.readUint16LE(); + s.seek(10, SEEK_CUR); _walkCount = s.readByte(); _allow = s.readByte(); diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 2ac2e16da0..2a52ec4d33 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -152,7 +152,7 @@ public: static void setVm(SherlockEngine *vm); public: Common::String _name; // Name - Common::String _description; // Description + char _description[41]; // Description lines Common::String _examine; // Examine in-depth description int _sequenceOffset; uint8 *_sequences; // Holds animation sequences diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index 4b087b59b5..3915a4b5d9 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -297,13 +297,13 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette) { ImageFrame frame; frame._width = stream.readUint16LE() + 1; frame._height = stream.readUint16LE() + 1; - frame._flags = stream.readByte(); + frame._paletteBase = stream.readByte(); frame._offset.x = stream.readUint16LE(); frame._offset.y = stream.readByte(); frame._rleEncoded = !skipPalette && (frame._offset.x == 1); - if (frame._flags & 0xFF) { + if (frame._paletteBase) { // Nibble packed frame data frame._size = (frame._width * frame._height) / 2; } else if (frame._rleEncoded) { @@ -351,8 +351,13 @@ void ImageFile::loadPalette(Common::SeekableReadStream &stream) { void ImageFile::decompressFrame(ImageFrame &frame, const byte *src) { frame._frame.create(frame._width, frame._height, Graphics::PixelFormat::createFormatCLUT8()); - if (frame._flags & 0xFF) { - error("TODO: ImageFile::decompressFrame() 4-bits/pixel\n"); + if (frame._paletteBase) { + // Nibble-packed + byte *pDest = (byte *)frame._frame.getPixels(); + for (int idx = 0; idx < frame._size; ++idx, ++src) { + *pDest++ = *src & 0xF; + *pDest++ = (*src >> 4); + } } else if (frame._rleEncoded) { // RLE encoded byte *dst = (byte *)frame._frame.getPixels(); diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h index ab2eb82a1e..45fda565bc 100644 --- a/engines/sherlock/resources.h +++ b/engines/sherlock/resources.h @@ -91,7 +91,7 @@ public: struct ImageFrame { uint32 _size; uint16 _width, _height; - int _flags; + int _paletteBase; bool _rleEncoded; Common::Point _offset; byte _rleMarker; diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 18ccdd4050..578eba2c24 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -212,7 +212,7 @@ void Scene::freeScene() { _walkData.clear(); _cAnim.clear(); _bgShapes.clear(); - _roomBounds.clear(); + _bounds.clear(); _canimShapes.clear(); for (uint idx = 0; idx < _images.size(); ++idx) @@ -241,8 +241,8 @@ bool Scene::loadScene(const Common::String &filename) { _ongoingCans = 0; // Reset the list of walkable areas - _roomBounds.clear(); - _roomBounds.push_back(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + _bounds.clear(); + _bounds.push_back(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); _descText.clear(); _comments = ""; @@ -281,7 +281,7 @@ bool Scene::loadScene(const Common::String &filename) { decompressLZ(*rrmStream, bgHeader._numImages * 569 + bgHeader._descSize + bgHeader._seqSize); - _bgShapes.resize(bgHeader._numStructs + 1); + _bgShapes.resize(bgHeader._numStructs); for (int idx = 0; idx < bgHeader._numStructs; ++idx) _bgShapes[idx].synchronize(*infoStream); @@ -305,13 +305,13 @@ bool Scene::loadScene(const Common::String &filename) { _images[idx + 1]._maxFrames = bgInfo[idx]._maxFrames; // Read in the image data - Common::SeekableReadStream *imageStream = !_lzwMode ? rrmStream : - decompressLZ(*rrmStream, bgInfo[idx]._filesize); + Common::SeekableReadStream *imageStream = _lzwMode ? + decompressLZ(*rrmStream, bgInfo[idx]._filesize) : + rrmStream->readStream(bgInfo[idx]._filesize); _images[idx + 1]._images = new ImageFile(*imageStream); - if (_lzwMode) - delete imageStream; + delete imageStream; } // Set up the bgShapes @@ -331,44 +331,41 @@ bool Scene::loadScene(const Common::String &filename) { &(*_bgShapes[idx]._images)[0]; } - // Set up end of list - _bgShapes[bgHeader._numStructs]._sequences = &_sequenceBuffer[0] + bgHeader._seqSize; - _bgShapes[bgHeader._numStructs]._examine = nullptr; - // Load in cAnim list - Common::SeekableReadStream *canimStream = !_lzwMode ? rrmStream : - decompressLZ(*rrmStream, 65 * bgHeader._numcAnimations); + Common::SeekableReadStream *canimStream = _lzwMode ? + decompressLZ(*rrmStream, 65 * bgHeader._numcAnimations) : + rrmStream->readStream(65 * bgHeader._numcAnimations); _cAnim.resize(bgHeader._numcAnimations); for (uint idx = 0; idx < _cAnim.size(); ++idx) _cAnim[idx].synchronize(*canimStream); - if (_lzwMode) - delete canimStream; + delete canimStream; // Read in the room bounding areas int size = rrmStream->readUint16LE(); Common::SeekableReadStream *boundsStream = !_lzwMode ? rrmStream : decompressLZ(*rrmStream, size); - _roomBounds.resize(size / 10); - for (uint idx = 0; idx < _roomBounds.size(); ++idx) { - _roomBounds[idx].left = boundsStream->readSint16LE(); - _roomBounds[idx].top = boundsStream->readSint16LE(); - _roomBounds[idx].setWidth(boundsStream->readSint16LE()); - _roomBounds[idx].setHeight(boundsStream->readSint16LE()); + _bounds.resize(size / 10); + for (uint idx = 0; idx < _bounds.size(); ++idx) { + _bounds[idx].left = boundsStream->readSint16LE(); + _bounds[idx].top = boundsStream->readSint16LE(); + _bounds[idx].setWidth(boundsStream->readSint16LE()); + _bounds[idx].setHeight(boundsStream->readSint16LE()); boundsStream->skip(2); // Skip unused scene number field } if (_lzwMode) delete boundsStream; - // Back at version byte, so skip over it - rrmStream->skip(1); + // Ensure we've reached the path version byte + if (rrmStream->readByte() != 254) + error("Invalid scene path data"); // Load the walk directory - for (int idx1 = 0; idx1 < MAX_ZONES; ++idx1) { - for (int idx2 = 0; idx2 < MAX_ZONES; ++idx2) + for (uint idx1 = 0; idx1 < _bounds.size(); ++idx1) { + for (uint idx2 = 0; idx2 < _bounds.size(); ++idx2) _walkDirectory[idx1][idx2] = rrmStream->readSint16LE(); } diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 3cdb20ac0f..a6e4f51b99 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -157,7 +157,7 @@ public: int _invGraphicItems; Common::String _comments; Common::Array _descText; - Common::Array _roomBounds; + Common::Array _bounds; Common::Array _bgShapes; Common::Array _cAnim; Common::Array _sequenceBuffer; -- cgit v1.2.3 From 0f424da24b8d5c3399714d56c896e3a46983faac Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 22 Mar 2015 15:44:11 -0400 Subject: SHERLOCK: First game scene is partially showing --- engines/sherlock/objects.h | 3 +++ engines/sherlock/scene.cpp | 14 +++++++------- engines/sherlock/sherlock.cpp | 7 ++++--- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 2a52ec4d33..9e43c087b8 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -206,6 +206,9 @@ public: void setFlagsAndToggles(); void adjustObject(); + + int frameWidth() const { return _imageFrame ? _imageFrame->_frame.w : 0; } + int frameHeight() const { return _imageFrame ? _imageFrame->_frame.h : 0; } }; struct CAnim { diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 578eba2c24..5bad8338aa 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -316,6 +316,10 @@ bool Scene::loadScene(const Common::String &filename) { // Set up the bgShapes for (int idx = 0; idx < bgHeader._numStructs; ++idx) { + _bgShapes[idx]._images = _images[_bgShapes[idx]._misc]._images; + _bgShapes[idx]._imageFrame = !_bgShapes[idx]._images ? (ImageFrame *)nullptr : + &(*_bgShapes[idx]._images)[0]; + _bgShapes[idx]._examine = Common::String(&_descText[_bgShapes[idx]._descOffset]); _bgShapes[idx]._sequences = &_sequenceBuffer[_bgShapes[idx]._sequenceOffset]; _bgShapes[idx]._misc = 0; @@ -325,10 +329,6 @@ bool Scene::loadScene(const Common::String &filename) { _bgShapes[idx]._frameNumber = -1; _bgShapes[idx]._position = Common::Point(0, 0); _bgShapes[idx]._oldSize = Common::Point(1, 1); - - _bgShapes[idx]._images = _images[_bgShapes[idx]._misc]._images; - _bgShapes[idx]._imageFrame = !_bgShapes[idx]._images ? (ImageFrame *)nullptr : - &(*_bgShapes[idx]._images)[0]; } // Load in cAnim list @@ -799,8 +799,8 @@ void Scene::updateBackground() { // Draw all static and active shapes that are FORWARD for (uint idx = 0; idx < _bgShapes.size(); ++idx) { _bgShapes[idx]._oldPosition = _bgShapes[idx]._position; - _bgShapes[idx]._oldSize = Common::Point(_bgShapes[idx]._imageFrame->_frame.w, - _bgShapes[idx]._imageFrame->_frame.h); + _bgShapes[idx]._oldSize = Common::Point(_bgShapes[idx].frameWidth(), + _bgShapes[idx].frameHeight()); if ((_bgShapes[idx]._type == ACTIVE_BG_SHAPE || _bgShapes[idx]._type == STATIC_BG_SHAPE) && _bgShapes[idx]._misc == FORWARD) @@ -837,7 +837,7 @@ void Scene::checkBgShapes(ImageFrame *frame, const Common::Point &pt) { Object &obj = _bgShapes[idx]; if (obj._type == STATIC_BG_SHAPE || obj._type == ACTIVE_BG_SHAPE) { if ((obj._flags & 5) == 1) { - obj._misc = (pt.y < (obj._position.y + obj._imageFrame->_frame.h - 1)) ? + obj._misc = (pt.y < (obj._position.y + obj.frameHeight() - 1)) ? NORMAL_FORWARD : NORMAL_BEHIND; } else if (!(obj._flags & 1)) { obj._misc = BEHIND; diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index ad590e3ffd..211c52ea87 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -54,14 +54,14 @@ SherlockEngine::~SherlockEngine() { delete _animation; delete _debugger; delete _events; - delete _inventory; delete _journal; delete _people; - delete _res; delete _scene; delete _screen; delete _sound; delete _talk; + delete _inventory; + delete _res; } void SherlockEngine::initialize() { @@ -111,7 +111,7 @@ Common::Error SherlockEngine::run() { } void SherlockEngine::sceneLoop() { - while (!shouldQuit() && _scene->_goToScene != -1) { + while (!shouldQuit() && _scene->_goToScene == -1) { // See if a script needs to be completed from either a goto room code, // or a script that was interrupted by another script if (_scriptMoreFlag == 1 || _scriptMoreFlag == 3) @@ -133,6 +133,7 @@ void SherlockEngine::sceneLoop() { void SherlockEngine::handleInput() { // TODO + _events->pollEventsAndWait(); } -- cgit v1.2.3 From 61980291bd977b15158a00e9cb97b8887a3d11e9 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 22 Mar 2015 15:49:54 -0400 Subject: SHERLOCK: Disable intro for now --- engines/sherlock/sherlock.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 211c52ea87..5bb6500cf9 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -88,7 +88,8 @@ void SherlockEngine::initialize() { Common::Error SherlockEngine::run() { initialize(); - showOpening(); + // Temporarily disabled for now +// showOpening(); while (!shouldQuit()) { // Prepare for scene, and handle any game-specific scenes. This allows -- cgit v1.2.3 From 47fb0be0c77485741ca0352e2f2de663a49aede5 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 22 Mar 2015 17:30:06 -0400 Subject: SHERLOCK: Fix loading of player sprites --- engines/sherlock/resources.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index 3915a4b5d9..e499b698c1 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -301,7 +301,7 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette) { frame._offset.x = stream.readUint16LE(); frame._offset.y = stream.readByte(); - frame._rleEncoded = !skipPalette && (frame._offset.x == 1); + frame._rleEncoded = !skipPalette && (frame._offset.x & 0xff) == 1; if (frame._paletteBase) { // Nibble packed frame data -- cgit v1.2.3 From b3130796540a727822d429ab122258e8be3db463 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 22 Mar 2015 17:54:16 -0400 Subject: SHERLOCK: Fix positioning of scene sprites --- engines/sherlock/scene.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 5bad8338aa..2133da5056 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -327,7 +327,7 @@ bool Scene::loadScene(const Common::String &filename) { _bgShapes[idx]._seqCounter2 = 0; _bgShapes[idx]._seqStack = 0; _bgShapes[idx]._frameNumber = -1; - _bgShapes[idx]._position = Common::Point(0, 0); + _bgShapes[idx]._oldPosition = Common::Point(0, 0); _bgShapes[idx]._oldSize = Common::Point(1, 1); } -- cgit v1.2.3 From 989d26897436103ff475b9987645b06265076bda Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 22 Mar 2015 18:24:13 -0400 Subject: SHERLOCK: Fix placement of Sherlock --- engines/sherlock/objects.h | 3 +++ engines/sherlock/scene.cpp | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 9e43c087b8..8099c6b74f 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -117,6 +117,9 @@ public: void adjustSprite(); void checkSprite(); + + int frameWidth() const { return _imageFrame ? _imageFrame->_frame.w : 0; } + int frameHeight() const { return _imageFrame ? _imageFrame->_frame.h : 0; } }; struct ActionType { diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 2133da5056..9f549b4312 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -777,7 +777,8 @@ void Scene::updateBackground() { player._sequenceNumber == WALK_DOWNRIGHT || player._sequenceNumber == STOP_DOWNRIGHT; surface.transBlitFrom(player._imageFrame->_frame, - Common::Point(player._position.x / 100, player._position.y / 100), flipped); + Common::Point(player._position.x / 100, + player._position.y / 100 - player.frameHeight()), flipped); } // Draw all static and active shapes that are NORMAL and are in front of the player -- cgit v1.2.3 From 73085bf57034adc2dbf5994ce2c6930b416eee7d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 23 Mar 2015 20:34:34 -0400 Subject: SHERLOCK: Beginnings of UserInterface class --- engines/sherlock/animation.cpp | 4 +- engines/sherlock/events.cpp | 56 ++++--- engines/sherlock/events.h | 14 +- engines/sherlock/module.mk | 3 +- engines/sherlock/objects.cpp | 44 ++++-- engines/sherlock/objects.h | 3 + engines/sherlock/resources.cpp | 2 +- engines/sherlock/scene.cpp | 78 ++++----- engines/sherlock/scene.h | 22 +-- engines/sherlock/screen.h | 4 + engines/sherlock/sherlock.cpp | 15 +- engines/sherlock/sherlock.h | 3 +- engines/sherlock/user_interface.cpp | 306 ++++++++++++++++++++++++++++++++++++ engines/sherlock/user_interface.h | 91 +++++++++++ 14 files changed, 534 insertions(+), 111 deletions(-) create mode 100644 engines/sherlock/user_interface.cpp create mode 100644 engines/sherlock/user_interface.h diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 9d32746de4..e1687b5238 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -151,14 +151,14 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f events.wait(speed); } - if (events.isKeyPressed()) { + if (events.kbHit()) { Common::KeyState keyState = events.getKey(); if (keyState.keycode == Common::KEYCODE_ESCAPE || keyState.keycode == Common::KEYCODE_SPACE) { skipped = true; break; } - } else if (events._mouseClicked) { + } else if (events._pressed) { skipped = true; break; } diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index 1a09f0600e..a6b3c899cb 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -36,8 +36,10 @@ Events::Events(SherlockEngine *vm) { _cursorId = INVALID_CURSOR; _frameCounter = 1; _priorFrameTime = 0; - _mouseClicked = false; _mouseButtons = 0; + _pressed = _released = false; + _rightPressed = _rightReleased = false; + _oldButtons = _oldRightButton = false; } Events::~Events() { @@ -125,12 +127,16 @@ void Events::pollEvents() { case Common::EVENT_KEYUP: return; case Common::EVENT_LBUTTONDOWN: + _mouseButtons |= 1; + return; case Common::EVENT_RBUTTONDOWN: - _mouseClicked = true; + _mouseButtons |= 2; return; case Common::EVENT_LBUTTONUP: + _mouseButtons &= ~1; + return; case Common::EVENT_RBUTTONUP: - _mouseClicked = false; + _mouseButtons &= ~2; return; case Common::EVENT_MOUSEMOVE: _mousePos = event.mouse; @@ -180,7 +186,9 @@ bool Events::checkForNextFrameCounter() { */ void Events::clearEvents() { _pendingKeys.clear(); - _mouseClicked = false; + _pressed = _rightPressed = false; + _rightPressed = _rightReleased = false; + _oldButtons = _oldRightButton = false; } /** @@ -197,7 +205,7 @@ bool Events::delay(uint32 time, bool interruptable) { // For really short periods, simply delay by the desired amount pollEvents(); g_system->delayMillis(time); - bool result = !(interruptable && (isKeyPressed() || _mouseClicked)); + bool result = !(interruptable && (kbHit() || _pressed)); clearEvents(); return result; @@ -210,7 +218,7 @@ bool Events::delay(uint32 time, bool interruptable) { while (!_vm->shouldQuit() && g_system->getMillis() < delayEnd) { pollEventsAndWait(); - if (interruptable && (isKeyPressed() || _mouseClicked)) { + if (interruptable && (kbHit() || _pressed)) { clearEvents(); return false; } @@ -221,25 +229,33 @@ bool Events::delay(uint32 time, bool interruptable) { } /** - * Wait for the next frame + * Sets the pressed and released button flags depending on the value passed */ -void Events::waitForNextFrame() { - _mouseClicked = false; - _mouseButtons = 0; - - bool mouseClicked = false; - int mouseButtons = 0; +void Events::setButtonState() { + _released = _rightReleased = false; + if (_mouseButtons & 1) + _pressed = _oldButtons = true; + + if ((_mouseButtons & 1) == 0 && _oldButtons) { + _pressed = _oldButtons = false; + _released = true; + } - uint32 frameCtr = getFrameCounter(); - while (!_vm->shouldQuit() && frameCtr == _frameCounter) { - pollEventsAndWait(); + if (_mouseButtons & 2) + _rightPressed = _oldRightButton = true; - mouseClicked |= _mouseClicked; - mouseButtons |= _mouseButtons; + if ((_mouseButtons & 2) == 0 && _oldRightButton) { + _rightPressed = _oldRightButton = false; + _rightReleased = true; } +} - _mouseClicked = mouseClicked; - _mouseButtons = mouseButtons; +/** + * Checks to see to see if a key or a mouse button is pressed. + */ +bool Events::checkInput() { + setButtonState(); + return kbHit() || _pressed || _released || _rightPressed || _rightReleased; } } // End of namespace MADS diff --git a/engines/sherlock/events.h b/engines/sherlock/events.h index e939b5768f..1c5fbc5be4 100644 --- a/engines/sherlock/events.h +++ b/engines/sherlock/events.h @@ -44,12 +44,17 @@ private: uint32 _priorFrameTime; Common::Point _mousePos; ImageFile *_cursorImages; + int _mouseButtons; bool checkForNextFrameCounter(); public: CursorId _cursorId; - byte _mouseButtons; - bool _mouseClicked; + bool _pressed; + bool _released; + bool _rightPressed; + bool _rightReleased; + bool _oldButtons; + bool _oldRightButton; Common::Stack _pendingKeys; public: Events(SherlockEngine *vm); @@ -75,7 +80,7 @@ public: uint32 getFrameCounter() const { return _frameCounter; } - bool isKeyPressed() const { return !_pendingKeys.empty(); } + bool kbHit() const { return !_pendingKeys.empty(); } Common::KeyState getKey() { return _pendingKeys.pop(); } @@ -85,8 +90,9 @@ public: bool delay(uint32 time, bool interruptable = false); - void waitForNextFrame(); + void setButtonState(); + bool checkInput(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk index aa8f495742..4101769a80 100644 --- a/engines/sherlock/module.mk +++ b/engines/sherlock/module.mk @@ -20,7 +20,8 @@ MODULE_OBJS = \ screen.o \ sherlock.o \ sound.o \ - talk.o + talk.o \ + user_interface.o # This module can be built as a plugin ifdef BUILD_PLUGINS diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 7d86c45e15..e0a24c5b7d 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -39,10 +39,6 @@ namespace Sherlock { #define CLEAR_DIST_X 5 #define CLEAR_DIST_Y 0 -#define INFO_FOREGROUND 11 -#define INFO_BACKGROUND 1 - - SherlockEngine *Sprite::_vm; /** @@ -779,6 +775,7 @@ int Object::checkNameForCodes(const Common::String &name, Common::StringArray *m Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; Talk &talk = *_vm->_talk; + UserInterface &ui = *_vm->_ui; bool printed = false; char ch; const char *p; @@ -852,19 +849,19 @@ int Object::checkNameForCodes(const Common::String &name, Common::StringArray *m } else if (name.hasPrefix("!")) { // Message attached to canimation int messageNum = atoi(name.c_str() + 1); - scene._infoFlag++; - scene.clearInfo(); + ui._infoFlag++; + ui.clearInfo(); screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, INFO_BACKGROUND, (*messages)[messageNum].c_str()); - _vm->_menuCounter = 25; + ui._menuCounter = 25; } else if (name.hasPrefix("@")) { // Message attached to canimation - scene._infoFlag++; - scene.clearInfo(); + ui._infoFlag++; + ui.clearInfo(); screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, INFO_BACKGROUND, "%s", name.c_str() + 1); printed = true; - _vm->_menuCounter = 25; + ui._menuCounter = 25; } return printed; @@ -922,6 +919,33 @@ void Object::adjustObject() { } } +/** + * Returns the current bounds for the sprite + */ +const Common::Rect Object::getNewBounds() const { + Common::Point pt = _position; + if (_imageFrame) + pt += _imageFrame->_offset; + + return Common::Rect(pt.x, pt.y, pt.x + frameWidth(), pt.y + frameHeight()); +} + +/** + * Returns the bounds for a sprite without a shape + */ +const Common::Rect Object::getNoShapeBounds() const { + return Common::Rect(_position.x, _position.y, + _position.x + _noShapeSize.x, _position.y + _noShapeSize.y); +} + +/** + * Returns the old bounsd for the sprite from the previous frame + */ +const Common::Rect Object::getOldBounds() const { + return Common::Rect(_oldPosition.x, _oldPosition.y, + _oldPosition.x + _oldSize.x, _oldPosition.y + _oldSize.y); +} + /*----------------------------------------------------------------*/ void CAnim::synchronize(Common::SeekableReadStream &s) { diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 8099c6b74f..4944681ab3 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -212,6 +212,9 @@ public: int frameWidth() const { return _imageFrame ? _imageFrame->_frame.w : 0; } int frameHeight() const { return _imageFrame ? _imageFrame->_frame.h : 0; } + const Common::Rect getNewBounds() const; + const Common::Rect getNoShapeBounds() const; + const Common::Rect getOldBounds() const; }; struct CAnim { diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index e499b698c1..878747a63c 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -354,7 +354,7 @@ void ImageFile::decompressFrame(ImageFrame &frame, const byte *src) { if (frame._paletteBase) { // Nibble-packed byte *pDest = (byte *)frame._frame.getPixels(); - for (int idx = 0; idx < frame._size; ++idx, ++src) { + for (uint idx = 0; idx < frame._size; ++idx, ++src) { *pDest++ = *src & 0xF; *pDest++ = (*src >> 4); } diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 9f549b4312..6e09693807 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -27,37 +27,6 @@ namespace Sherlock { -// Main Menu control locations -const int MENU_POINTS[12][4] = { - { 13, 153, 72, 165 }, - { 13, 169, 72, 181 }, - { 13, 185, 72, 197 }, - { 88, 153, 152, 165 }, - { 88, 169, 152, 181 }, - { 88, 185, 152, 197 }, - { 165, 153, 232, 165 }, - { 165, 169, 232, 181 }, - { 165, 185, 233, 197 }, - { 249, 153, 305, 165 }, - { 249, 169, 305, 181 }, - { 249, 185, 305, 197 } -}; - -// Inventory control locations */ -const int INVENTORY_POINTS[8][3] = { - { 4, 50, 28 }, - { 52, 99, 76 }, - { 101, 140, 122 }, - { 142, 187, 165 }, - { 189, 219, 197 }, - { 221, 251, 233 }, - { 253, 283, 265 }, - { 285, 315, 293 } -}; - -/*----------------------------------------------------------------*/ - - void BgFileHeader::synchronize(Common::SeekableReadStream &s) { _numStructs = s.readUint16LE(); _numImages = s.readUint16LE(); @@ -121,8 +90,6 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { _goToScene = -1; _changes = false; _charPoint = _oldCharPoint = 0; - _windowOpen = false; - _infoFlag = false; _keyboardInput = 0; _walkedInScene = false; _ongoingCans = 0; @@ -132,23 +99,19 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { _hsavedPos = Common::Point(-1, -1); _hsavedFs = -1; _cAnimFramePause = 0; - _menuMode = STD_MODE; _invMode = INVMODE_0; _restoreFlag = false; _invLookFlag = false; _lookHelp = false; _animating = 0; _doBgAnimDone = true; - _oldLook = 0; _tempFadeStyle = 0; _controlPanel = new ImageFile("controls.vgs"); - _controls = nullptr; // new ImageFile("menu.all"); } Scene::~Scene() { delete _controlPanel; - delete _controls; freeScene(); } @@ -159,10 +122,11 @@ void Scene::selectScene() { Events &events = *_vm->_events; People &people = *_vm->_people; Screen &screen = *_vm->_screen; + UserInterface &ui = *_vm->_ui; // Reset fields - _windowOpen = _infoFlag = false; - _menuMode = STD_MODE; + ui._windowOpen = ui._infoFlag = false; + ui._menuMode = STD_MODE; _keyboardInput = 0; _oldKey = _help = _oldHelp = 0; _oldTemp = _temp = 0; @@ -1135,6 +1099,7 @@ void Scene::doBgAnim() { Screen &screen = *_vm->_screen; Sound &sound = *_vm->_sound; Talk &talk = *_vm->_talk; + UserInterface &ui = *_vm->_ui; Surface surface = screen._backBuffer.getSubArea(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); int cursorId = events.getCursor(); @@ -1151,7 +1116,7 @@ void Scene::doBgAnim() { } // Check for setting magnifying glass cursor - if (_menuMode == INV_MODE || _menuMode == USE_MODE || _menuMode == GIVE_MODE) { + if (ui._menuMode == INV_MODE || ui._menuMode == USE_MODE || ui._menuMode == GIVE_MODE) { if (_invMode == INVMODE_1) { // Only show Magnifying glass cursor if it's not on the inventory command line if (mousePos.y < CONTROLS_Y || mousePos.y >(CONTROLS_Y1 + 13)) @@ -1434,20 +1399,33 @@ void Scene::doBgAnim() { } } +void Scene::saveSceneStatus() { + // TODO +} + /** - * Clears the info line of the screen + * Attempts to find a background shape within the passed bounds. If found, + * it will return the shape number, or -1 on failure. */ -void Scene::clearInfo() { - if (_infoFlag) { - _vm->_screen->fillRect(16, INFO_LINE, SHERLOCK_SCREEN_WIDTH - 200, INFO_LINE + 9, - INFO_BLACK); - _infoFlag = false; - _oldLook = -1; +int Scene::findBgShape(const Common::Rect &r) { + if (!_doBgAnimDone) + // New frame hasn't been drawn yet + return -1; + + for (int idx = (int)_bgShapes.size() - 1; idx >= 0; --idx) { + Object &o = _bgShapes[idx]; + if (o._type != INVALID && o._type != NO_SHAPE && o._type != HIDDEN + && o._aType <= PERSON) { + if (r.intersects(o.getNewBounds())) + return idx; + } else if (o._type == NO_SHAPE) { + if (r.intersects(o.getNoShapeBounds())) + return idx; + } } -} -void Scene::saveSceneStatus() { - // TODO + return -1; } + } // End of namespace Sherlock diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index a6e4f51b99..785ed63106 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -37,22 +37,6 @@ namespace Sherlock { #define CONTROLS_Y 138 #define CONTROLS_Y1 151 -enum MenuMode { - STD_MODE = 0, - LOOK_MODE = 1, - MOVE_MODE = 2, - TALK_MODE = 3, - PICKUP_MODE = 4, - OPEN_MODE = 5, - CLOSE_MODE = 6, - INV_MODE = 7, - USE_MODE = 8, - GIVE_MODE = 9, - JOURNAL_MODE = 10, - FILES_MODE = 11, - SETUP_MODE = 12 -}; - enum InvMode { INVMODE_0 = 0, INVMODE_1 = 1, @@ -114,13 +98,11 @@ private: Common::String _rrmName; int _cAnimFramePause; Common::String _cAnimStr; - MenuMode _menuMode; InvMode _invMode; bool _lookScriptFlag; int _selector; bool _invLookFlag; bool _lookHelp; - int _oldLook; bool loadScene(const Common::String &filename); @@ -144,9 +126,7 @@ public: Common::Point _bigPos; Common::Point _overPos; int _charPoint, _oldCharPoint; - ImageFile *_controls; ImageFile *_controlPanel; - bool _windowOpen, _infoFlag; int _keyboardInput; int _oldKey, _help, _oldHelp; int _oldTemp, _temp; @@ -195,6 +175,8 @@ public: void doBgAnim(); void clearInfo(); + + int findBgShape(const Common::Rect &r); }; } // End of namespace Sherlock diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 87453ba36d..419ae681c2 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -34,7 +34,11 @@ namespace Sherlock { #define PALETTE_SIZE 768 #define PALETTE_COUNT 256 #define VGA_COLOR_TRANS(x) ((x) * 255 / 63) + #define INFO_BLACK 1 +#define INFO_FOREGROUND 11 +#define INFO_BACKGROUND 1 + class SherlockEngine; diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 5bb6500cf9..eea40f33a6 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -41,12 +41,12 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _screen = nullptr; _sound = nullptr; _talk = nullptr; + _ui = nullptr; _useEpilogue2 = false; _justLoaded = false; _loadingSavedGame = false; _onChessboard = false; _slowChess = false; - _menuCounter = 0; _scriptMoreFlag = 0; } @@ -60,6 +60,7 @@ SherlockEngine::~SherlockEngine() { delete _screen; delete _sound; delete _talk; + delete _ui; delete _inventory; delete _res; } @@ -83,6 +84,7 @@ void SherlockEngine::initialize() { _screen = new Screen(this); _sound = new Sound(this); _talk = new Talk(this); + _ui = new UserInterface(this); } Common::Error SherlockEngine::run() { @@ -132,9 +134,18 @@ void SherlockEngine::sceneLoop() { } +/** + * Handle all player input + */ void SherlockEngine::handleInput() { - // TODO + bool personFound; + _events->pollEventsAndWait(); + + // See if a key or mouse button is pressed + _events->setButtonState(); + + _ui->handleInput(); } diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index b84f6d7429..392f55839e 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -42,6 +42,7 @@ #include "sherlock/screen.h" #include "sherlock/sound.h" #include "sherlock/talk.h" +#include "sherlock/user_interface.h" namespace Sherlock { @@ -90,6 +91,7 @@ public: Screen *_screen; Sound *_sound; Talk *_talk; + UserInterface *_ui; Common::RandomSource _randomSource; Common::Array _flags; Common::String _soundOverride; @@ -102,7 +104,6 @@ public: Common::Array _map; // Map locations for each scene bool _onChessboard; bool _slowChess; - int _menuCounter; int _scriptMoreFlag; Common::String _scriptName; public: diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp new file mode 100644 index 0000000000..d80aaecb54 --- /dev/null +++ b/engines/sherlock/user_interface.cpp @@ -0,0 +1,306 @@ +/* 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 "sherlock/user_interface.h" +#include "sherlock/sherlock.h" + +namespace Sherlock { + +// Main user interface menu control locations +const int MENU_POINTS[12][4] = { + { 13, 153, 72, 165 }, + { 13, 169, 72, 181 }, + { 13, 185, 72, 197 }, + { 88, 153, 152, 165 }, + { 88, 169, 152, 181 }, + { 88, 185, 152, 197 }, + { 165, 153, 232, 165 }, + { 165, 169, 232, 181 }, + { 165, 185, 233, 197 }, + { 249, 153, 305, 165 }, + { 249, 169, 305, 181 }, + { 249, 185, 305, 197 } +}; + +// Inventory control locations */ +const int INVENTORY_POINTS[8][3] = { + { 4, 50, 28 }, + { 52, 99, 76 }, + { 101, 140, 122 }, + { 142, 187, 165 }, + { 189, 219, 197 }, + { 221, 251, 233 }, + { 253, 283, 265 }, + { 285, 315, 293 } +}; + +const char COMMANDS[13] = "LMTPOCIUGJFS"; + +/*----------------------------------------------------------------*/ + +UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { + _bgFound = 0; + _oldBgFound = -1; + _keycode = Common::KEYCODE_INVALID; + _helpStyle = 0; + _menuCounter = 0; + _menuMode = STD_MODE; + _help = _oldHelp = 0; + _lookHelp = 0; + _key = _oldKey = 0; + _temp = _oldTemp = 0; + _invLookFlag = 0; + _windowOpen = false; + _oldLook = false; + _keyboardInput = false; + + _controls = nullptr; // new ImageFile("menu.all"); +} + +UserInterface::~UserInterface() { + delete _controls; +} + +void UserInterface::handleInput() { + Events &events = *_vm->_events; + Scene &scene = *_vm->_scene; + Screen &screen = *_vm->_screen; + + if (_menuCounter) + whileMenuCounter(); + + Common::Point pt = events.mousePos(); + _bgFound = scene.findBgShape(Common::Rect(pt.x, pt.y, pt.x + 1, pt.y + 1)); + _keycode = Common::KEYCODE_INVALID; + + // Check kbd and set the mouse released flag if Enter or space is pressed. + // Otherwise, the pressed key is stored for later use + if (events.kbHit()) { + Common::KeyState keyState = events.getKey(); + + if (keyState.keycode == Common::KEYCODE_x && keyState.flags & Common::KBD_ALT) { + _vm->quitGame(); + return; + } else if (keyState.keycode == Common::KEYCODE_SPACE || + keyState.keycode == Common::KEYCODE_RETURN) { + events._pressed = events._oldButtons = 0; + _keycode = Common::KEYCODE_INVALID; + } + } + + // Do button highlighting check + if (!_vm->_scriptMoreFlag) { // Don't if scripts are running + if (((events._rightPressed || events._rightReleased) && _helpStyle) || + (!_helpStyle && !_menuCounter)) { + // Handle any default commands if we're in STD_MODE + if (_menuMode == STD_MODE) { + if (pt.y < CONTROLS_Y && + (events._rightPressed || (!_helpStyle && !events._released)) && + (_bgFound != -1) && (_bgFound < 1000) && + (scene._bgShapes[_bgFound]._defaultCommand || + scene._bgShapes[_bgFound]._description[0])) { + // If there is no default command, so set it to Look + if (scene._bgShapes[_bgFound]._defaultCommand) + _help = scene._bgShapes[_bgFound]._defaultCommand - 1; + else + _help = 0; + + // Reset 'help' if it is an invalid command + if (_help > 5) + _help = -1; + } else if (pt.y < CONTROLS_Y && + ((events._rightReleased && _helpStyle) || (events._released && !_helpStyle)) && + (_bgFound != -1 && _bgFound < 1000) && + (scene._bgShapes[_bgFound]._defaultCommand || + scene._bgShapes[_bgFound]._description[0])) { + // If there is no default command, set it to Look + if (scene._bgShapes[_bgFound]._defaultCommand) + _menuMode = (MenuMode)scene._bgShapes[_bgFound]._defaultCommand; + else + _menuMode = LOOK_MODE; + events._released = true; + events._pressed = events._oldButtons = false; + _help = _oldHelp = -1; + + if (_menuMode == LOOK_MODE) { + // Set the flag to tell the game that this was a right-click + // call to look and should exit without the look button being pressed + _lookHelp = true; + } + } else { + _help = -1; + } + + // Check if highlighting a different button than last time + if (_help != _oldHelp) { + // If another button was highlighted previously, restore it + if (_oldHelp != -1) + restoreButton(_oldHelp); + + // If we're highlighting a new button, then draw it pressed + if (_help != -1) + depressButton(_help); + + _help = _oldHelp; + } + + if (_bgFound != _oldBgFound) { + _infoFlag = true; + clearInfo(); + + if (_help != -1 && (scene._bgShapes[_bgFound]._description[0] != 32 && + scene._bgShapes[_bgFound]._description[0])) + screen.print(Common::Point(0, INFO_LINE + 1), + INFO_FOREGROUND, INFO_BACKGROUND, "%s", + scene._bgShapes[_bgFound]._description); + } + } else { + // We're not in STD_MODE + // If there isn't a window open, then revert back to STD_MODE + if (!_windowOpen && events._rightReleased) { + // Restore all buttons + for (int idx = 0; idx < 12; ++idx) + restoreButton(idx); + + _menuMode = STD_MODE; + _key = _oldKey = -1; + _temp = _oldTemp = _lookHelp = _invLookFlag = 0; + events.clearEvents(); + } + } + } + } + + // TODO +} + +/** + * Draws the image for a user interface button in the down/pressed state. + */ +void UserInterface::depressButton(int num) { + Screen &screen = *_vm->_screen; + Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]); + + Graphics::Surface &s = (*_controls)[num]._frame; + screen._backBuffer.transBlitFrom(s, pt); + screen.slamArea(pt.x, pt.y, pt.x + s.w, pt.y + s.h); +} + +/** + * Draws the image for the given user interface button in the up + * (not selected) position + */ +void UserInterface::restoreButton(int num) { + Screen &screen = *_vm->_screen; + Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]); + + screen._backBuffer.blitFrom(screen._backBuffer2, pt, + Common::Rect(pt.x, pt.y, pt.x + 90, pt.y + 19)); + screen._backBuffer.blitFrom(screen._backBuffer, pt, + Common::Rect(pt.x, pt.y, pt.x + (*_controls)[num]._frame.w, + (*_controls)[num]._frame.h)); + + if (!_menuCounter) { + _infoFlag++; + clearInfo(); + } +} + +/** + * If he mouse button is pressed, then calls depressButton to draw the button + * as pressed; if not, it will show it as released with a call to "restoreButton". + */ +void UserInterface::pushButton(int num) { + Events &events = *_vm->_events; + _oldKey = -1; + + if (!events._released) { + if (_oldHelp != -1) + restoreButton(_oldHelp); + if (_help != -1) + restoreButton(_help); + + depressButton(num); + events.wait(6); + } + + restoreButton(num); +} + +/** + * By the time this method has been called, the graphics for the button change + * have already been drawn. This simply takes care of switching the mode around + * accordingly + */ +void UserInterface::toggleButton(int num) { + Screen &screen = *_vm->_screen; + + if (_menuMode != (num + 1)) { + _menuMode = (MenuMode)(num + 1); + _oldKey = COMMANDS[num]; + _oldTemp = num; + + if (_keyboardInput) { + if (_oldHelp != -1 && _oldHelp != num) + restoreButton(_oldHelp); + if (_help != -1 && _help != num) + restoreButton(_help); + + _keyboardInput = false; + + Graphics::Surface &s = (*_controls)[num]._frame; + Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]); + screen._backBuffer.transBlitFrom(s, pt); + screen.slamArea(pt.x, pt.y, pt.x + s.w, pt.y + s.h); + } + } else { + _menuMode = STD_MODE; + _oldKey = -1; + restoreButton(num); + } +} + + +/** + * Clears the info line of the screen + */ +void UserInterface::clearInfo() { + if (_infoFlag) { + _vm->_screen->fillRect(16, INFO_LINE, SHERLOCK_SCREEN_WIDTH - 200, INFO_LINE + 9, + INFO_BLACK); + _infoFlag = false; + _oldLook = -1; + } +} + +/** + * Handles counting down whilst checking for input, then clears the info line. + */ +void UserInterface::whileMenuCounter() { + if (!(--_menuCounter) || _vm->_events->checkInput()) { + _menuCounter = 0; + ++_infoFlag; + clearInfo(); + } +} + +} // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h new file mode 100644 index 0000000000..4a98a5be89 --- /dev/null +++ b/engines/sherlock/user_interface.h @@ -0,0 +1,91 @@ +/* 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 SHERLOCK_UI_H +#define SHERLOCK_UI_H + +#include "common/scummsys.h" +#include "common/events.h" +#include "sherlock/resources.h" + +namespace Sherlock { + +enum MenuMode { + STD_MODE = 0, + LOOK_MODE = 1, + MOVE_MODE = 2, + TALK_MODE = 3, + PICKUP_MODE = 4, + OPEN_MODE = 5, + CLOSE_MODE = 6, + INV_MODE = 7, + USE_MODE = 8, + GIVE_MODE = 9, + JOURNAL_MODE = 10, + FILES_MODE = 11, + SETUP_MODE = 12 +}; + +class SherlockEngine; + +class UserInterface { +private: + SherlockEngine *_vm; + int _bgFound; + int _oldBgFound; + Common::KeyCode _keycode; + int _helpStyle; + int _lookHelp; + int _help, _oldHelp; + int _key, _oldKey; + int _temp, _oldTemp; + int _invLookFlag; + ImageFile *_controls; + int _oldLook; + bool _keyboardInput; +private: + void depressButton(int num); + + void restoreButton(int num); + + void pushButton(int num); + + void toggleButton(int num); +public: + MenuMode _menuMode; + int _menuCounter; + bool _infoFlag; + bool _windowOpen; +public: + UserInterface(SherlockEngine *vm); + ~UserInterface(); + + void handleInput(); + + void clearInfo(); + + void whileMenuCounter(); +}; + +} // End of namespace Sherlock + +#endif -- cgit v1.2.3 From 73de00b72f002c09c173226e85b0f96f35551d10 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 23 Mar 2015 21:52:20 -0400 Subject: SHERLOCK: Implemented UserInterface::handleInput --- engines/sherlock/people.cpp | 4 + engines/sherlock/people.h | 4 +- engines/sherlock/scene.cpp | 22 +++++ engines/sherlock/scene.h | 2 + engines/sherlock/sherlock.cpp | 2 - engines/sherlock/talk.cpp | 4 + engines/sherlock/talk.h | 2 + engines/sherlock/user_interface.cpp | 185 +++++++++++++++++++++++++++++++++++- engines/sherlock/user_interface.h | 16 ++++ 9 files changed, 237 insertions(+), 4 deletions(-) diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 91689e296c..8a8dcb5245 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -311,4 +311,8 @@ void People::walkToCoords(const Common::Point &destPos, int destDir) { warning("TODO: walkToCoords"); } +void People::goAllTheWay() { + // TODO +} + } // End of namespace Sherlock diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index de84675e66..8d1953ee20 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -59,7 +59,6 @@ private: Sprite &_player; bool _walkLoaded; int _oldWalkSequence; - bool _allowWalkAbort; public: Common::Point _walkDest; Common::Stack _walkTo; @@ -67,6 +66,7 @@ public: bool _portraitLoaded; Object _portrait; bool _clearingThePortrait; + bool _allowWalkAbort; public: People(SherlockEngine *vm); ~People(); @@ -86,6 +86,8 @@ public: void gotoStand(Sprite &sprite); void walkToCoords(const Common::Point &destPos, int destDir); + + void goAllTheWay(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 6e09693807..95e8355957 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -1427,5 +1427,27 @@ int Scene::findBgShape(const Common::Rect &r) { return -1; } +/** + * Checks to see if the given position in the scene belongs to a given zone type. + * If it is, the zone is activated and used just like a TAKL zone or aFLAG_SET zone. + */ +int Scene::checkForZones(const Common::Point &pt, int zoneType) { + int matches = 0; + + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + Object &o = _bgShapes[idx]; + if ((o._aType == zoneType && o._type != INVALID) && o._type != HIDDEN) { + Common::Rect r = o._type == NO_SHAPE ? o.getNoShapeBounds() : o.getNewBounds(); + + if (r.contains(pt)) { + ++matches; + o.setFlagsAndToggles(); + _vm->_talk->talkTo(o._use[0]._target); + } + } + } + + return matches; +} } // End of namespace Sherlock diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 785ed63106..1a9fe7b02c 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -177,6 +177,8 @@ public: void clearInfo(); int findBgShape(const Common::Rect &r); + + int checkForZones(const Common::Point &pt, int zoneType); }; } // End of namespace Sherlock diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index eea40f33a6..a9de32972f 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -138,8 +138,6 @@ void SherlockEngine::sceneLoop() { * Handle all player input */ void SherlockEngine::handleInput() { - bool personFound; - _events->pollEventsAndWait(); // See if a key or mouse button is pressed diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 4c10b7b7ef..ff71d37a2f 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -34,6 +34,10 @@ void Talk::talkTo(const Common::String &name) { // TODO } +void Talk::talk(int objNum) { + // TODO +} + /** * Clear loaded talk data */ diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index fc73994cc6..9359b77e87 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -51,6 +51,8 @@ public: void talkTo(const Common::String &name); + void talk(int objNum); + void freeTalkVars(); }; diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index d80aaecb54..5ed5494c5e 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -72,6 +72,8 @@ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { _windowOpen = false; _oldLook = false; _keyboardInput = false; + _invMode = 0; + _pause = false; _controls = nullptr; // new ImageFile("menu.all"); } @@ -82,8 +84,10 @@ UserInterface::~UserInterface() { void UserInterface::handleInput() { Events &events = *_vm->_events; + People &people = *_vm->_people; Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; + Talk &talk = *_vm->_talk; if (_menuCounter) whileMenuCounter(); @@ -190,7 +194,146 @@ void UserInterface::handleInput() { } } - // TODO + // Reset the old bgshape number if the mouse button is released, so that + // it can e re-highlighted when we come back here + if ((events._rightReleased && _helpStyle) || (events._released && !_helpStyle)) + _oldBgFound = -1; + + // Do routines that should be done before input processing + switch (_menuMode) { + case LOOK_MODE: + if (!_windowOpen) { + if (events._released && _bgFound >= 0 && _bgFound < 1000) { + if (!scene._bgShapes[_bgFound]._examine.empty()) + examine(); + } else { + lookScreen(pt); + } + } + break; + + case MOVE_MODE: + case OPEN_MODE: + case CLOSE_MODE: + case PICKUP_MODE: + lookScreen(pt); + break; + + case TALK_MODE: + if (!_windowOpen) { + bool personFound; + + if (_bgFound >= 1000) { + personFound = false; + if (!events._released) + lookScreen(pt); + } else { + personFound = scene._bgShapes[_bgFound]._aType == PERSON && _bgFound != -1; + } + + if (events._released && personFound) + talk.talk(_bgFound); + else if (personFound) + lookScreen(pt); + else if (_bgFound < 1000) + clearInfo(); + } + break; + + case USE_MODE: + case GIVE_MODE: + case INV_MODE: + if (_invMode == 1 || _invMode == 2 || _invMode == 3) { + if (pt.y < CONTROLS_Y) + lookInv(); + else + lookScreen(pt); + } + break; + + default: + break; + } + + // + // Do input processing + // + if (events._pressed || events._released || events._rightPressed || + _keycode != Common::KEYCODE_INVALID || _pause) { + if (((events._released && (_helpStyle || _help == -1)) || (events._rightReleased && !_helpStyle)) && + (pt.y <= CONTROLS_Y) && (_menuMode == STD_MODE)) { + // The mouse was clicked in the playing area with no action buttons down. + // Check if the mouse was clicked in a script zone. If it was, + // then execute the script. Otherwise, walk to the given position + if (scene.checkForZones(pt, SCRIPT_ZONE) != 0) { + // Mouse clicked in script zone + events._pressed = events._released = false; + } else { + people._walkDest = pt; + people._allowWalkAbort = false; + people.goAllTheWay(); + } + + if (_oldKey != -1) { + restoreButton(_oldTemp); + _oldKey = -1; + } + } + + // Handle action depending on selected mode + switch (_menuMode) { + case LOOK_MODE: + if (_windowOpen) + doLookControl(); + break; + + case MOVE_MODE: + doMiscControl(ALLOW_MOVEMENT); + break; + + case TALK_MODE: + if (_windowOpen) + doTalkControl(); + break; + + case OPEN_MODE: + doMiscControl(ALLOW_OPEN); + break; + + case CLOSE_MODE: + doMiscControl(ALLOW_CLOSE); + break; + + case PICKUP_MODE: + doPickControl(); + break; + + case USE_MODE: + case GIVE_MODE: + case INV_MODE: + doInvControl(); + break; + + case FILES_MODE: + doEnvControl(); + break; + + default: + break; + } + + // As long as there isn't an open window, do main input processing. + // Windows are opened when in TALK, USE, INV, and GIVE modes + if ((!_windowOpen && !_menuCounter && pt.y > CONTROLS_Y) || + _keycode != Common::KEYCODE_INVALID) { + if (events._pressed || events._released || _pause || + _keycode != Common::KEYCODE_INVALID) + doMainControl(); + } + + if (pt.y < CONTROLS_Y && events._pressed && _oldTemp != (_menuMode - 1) && _oldKey != -1) + restoreButton(_oldTemp); + } } /** @@ -303,4 +446,44 @@ void UserInterface::whileMenuCounter() { } } +void UserInterface::examine() { + // TODO +} + +void UserInterface::lookScreen(const Common::Point &pt) { + // TODO +} + +void UserInterface::lookInv() { + // TODO +} + +void UserInterface::doEnvControl() { + // TODO +} + +void UserInterface::doInvControl() { + // TODO +} + +void UserInterface::doLookControl() { + // TODO +} + +void UserInterface::doMainControl() { + // TODO +} + +void UserInterface::doMiscControl(int allowed) { + // TODO +} + +void UserInterface::doPickControl() { + // TODO +} + +void UserInterface::doTalkControl() { + // TODO +} + } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index 4a98a5be89..d312ff919c 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -62,6 +62,8 @@ private: ImageFile *_controls; int _oldLook; bool _keyboardInput; + int _invMode; + bool _pause; private: void depressButton(int num); @@ -70,6 +72,20 @@ private: void pushButton(int num); void toggleButton(int num); + + void examine(); + + void lookScreen(const Common::Point &pt); + + void lookInv(); + + void doEnvControl(); + void doInvControl(); + void doLookControl(); + void doMainControl(); + void doMiscControl(int allowed); + void doPickControl(); + void doTalkControl(); public: MenuMode _menuMode; int _menuCounter; -- cgit v1.2.3 From d44a9e3f5a390837ce88b95d6afa2e7a5ee9e26e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 23 Mar 2015 22:27:07 -0400 Subject: SHERLOCK: Fix loading of user interface controls --- engines/sherlock/resources.cpp | 10 ++++++---- engines/sherlock/user_interface.cpp | 9 ++++++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index 878747a63c..1bedbe9b7b 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -300,7 +300,7 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette) { frame._paletteBase = stream.readByte(); frame._offset.x = stream.readUint16LE(); frame._offset.y = stream.readByte(); - + frame._rleEncoded = !skipPalette && (frame._offset.x & 0xff) == 1; if (frame._paletteBase) { @@ -332,16 +332,18 @@ void ImageFile::loadPalette(Common::SeekableReadStream &stream) { // Check for palette int v1 = stream.readUint16LE() + 1; int v2 = stream.readUint16LE() + 1; + stream.skip(1); // Skip paletteBase byte + bool rleEncoded = stream.readByte() == 1; int size = v1 * v2; - if ((size - 12) == PALETTE_SIZE) { + if ((size - 12) == PALETTE_SIZE && !rleEncoded) { // Found palette, so read it in - stream.seek(4 + 12, SEEK_CUR); + stream.seek(2 + 12, SEEK_CUR); for (int idx = 0; idx < PALETTE_SIZE; ++idx) _palette[idx] = VGA_COLOR_TRANS(stream.readByte()); } else { // Not a palette, so rewind to start of frame data for normal frame processing - stream.seek(-4, SEEK_CUR); + stream.seek(-6, SEEK_CUR); } } diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 5ed5494c5e..1cd5b80980 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -75,13 +75,16 @@ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { _invMode = 0; _pause = false; - _controls = nullptr; // new ImageFile("menu.all"); + _controls = new ImageFile("menu.all"); } UserInterface::~UserInterface() { delete _controls; } +/** + * Main input handler for the user interface + */ void UserInterface::handleInput() { Events &events = *_vm->_events; People &people = *_vm->_people; @@ -355,12 +358,12 @@ void UserInterface::depressButton(int num) { void UserInterface::restoreButton(int num) { Screen &screen = *_vm->_screen; Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]); + Graphics::Surface &frame = (*_controls)[num]._frame; screen._backBuffer.blitFrom(screen._backBuffer2, pt, Common::Rect(pt.x, pt.y, pt.x + 90, pt.y + 19)); screen._backBuffer.blitFrom(screen._backBuffer, pt, - Common::Rect(pt.x, pt.y, pt.x + (*_controls)[num]._frame.w, - (*_controls)[num]._frame.h)); + Common::Rect(pt.x, pt.y, pt.x + frame.w, pt.y + frame.h)); if (!_menuCounter) { _infoFlag++; -- cgit v1.2.3 From f2ee94c0ab646d3efe93e0c782494f5888d7cc36 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 24 Mar 2015 08:35:08 -0400 Subject: SHERLOCK: Implement font drawing --- engines/sherlock/graphics.cpp | 8 +++ engines/sherlock/graphics.h | 3 ++ engines/sherlock/resources.cpp | 5 +- engines/sherlock/screen.cpp | 105 ++++++++++++++++++++++++++++++++---- engines/sherlock/screen.h | 9 ++++ engines/sherlock/user_interface.cpp | 2 +- 6 files changed, 118 insertions(+), 14 deletions(-) diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index 63988a2f30..1a0144bc4b 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -90,6 +90,14 @@ void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt, copyRectToSurface(src, pt.x, pt.y, srcBounds); } +/** +* Draws an image frame at a given position within this surface with transparency +*/ +void Surface::transBlitFrom(const ImageFrame &src, const Common::Point &pt, + bool flipped, int overrideColor) { + transBlitFrom(src._frame, pt + src._offset, flipped, overrideColor); +} + /** * Draws a surface at a given position within this surface with transparency */ diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index b33495a2b9..c380d805b2 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -25,6 +25,7 @@ #include "common/rect.h" #include "graphics/surface.h" +#include "sherlock/resources.h" namespace Sherlock { @@ -43,6 +44,8 @@ public: void blitFrom(const Graphics::Surface &src, const Common::Point &pt); void blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds); + void transBlitFrom(const ImageFrame &src, const Common::Point &pt, + bool flipped = false, int overrideColor = 0); void transBlitFrom(const Graphics::Surface &src, const Common::Point &pt, bool flipped = false, int overrideColor = 0); diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index 1bedbe9b7b..0d66646286 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -298,10 +298,11 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette) { frame._width = stream.readUint16LE() + 1; frame._height = stream.readUint16LE() + 1; frame._paletteBase = stream.readByte(); - frame._offset.x = stream.readUint16LE(); + frame._rleEncoded = stream.readByte() == 1; + frame._offset.x = stream.readByte(); frame._offset.y = stream.readByte(); - frame._rleEncoded = !skipPalette && (frame._offset.x & 0xff) == 1; + frame._rleEncoded = !skipPalette && frame._rleEncoded; if (frame._paletteBase) { // Nibble packed frame data diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index f8f1d56e67..b1ad280b39 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -23,6 +23,7 @@ #include "sherlock/screen.h" #include "sherlock/sherlock.h" #include "common/system.h" +#include "common/util.h" #include "graphics/palette.h" namespace Sherlock { @@ -32,19 +33,29 @@ Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCR _backBuffer2(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT) { _transitionSeed = 1; _fadeStyle = false; + _font = nullptr; + _fontHeight = 0; Common::fill(&_cMap[0], &_cMap[PALETTE_SIZE], 0); Common::fill(&_sMap[0], &_sMap[PALETTE_SIZE], 0); setFont(1); } +Screen::~Screen() { + delete _font; +} + void Screen::setFont(int fontNumber) { _fontNumber = fontNumber; Common::String fname = Common::String::format("FONT%d.VGS", fontNumber); - Common::SeekableReadStream *stream = _vm->_res->load(fname); - debug("TODO: Loading font %s, size - %d", fname.c_str(), stream->size()); + // Discard any previous font and read in new one + delete _font; + _font = new ImageFile(fname); - delete stream; + // Iterate through the frames to find the tallest font character + _fontHeight = 0; + for (uint idx = 0; idx < _font->size(); ++idx) + _fontHeight = MAX((uint16)_fontHeight, (*_font)[idx]._frame.h); } void Screen::update() { @@ -231,14 +242,6 @@ void Screen::verticalTransition() { } } -/** - * Prints the text passed onto the back buffer at the given position and color. - * The string is then blitted to the screen - */ -void Screen::print(const Common::Point &pt, int fgColor, int bgColor, const char *format, ...) { - // TODO -} - /** * Copies a section of the second back buffer into the main back buffer */ @@ -294,4 +297,84 @@ void Screen::flushImage(ImageFrame *frame, const Common::Point &pt, *h = newBounds.height(); } +/** + * Prints the text passed onto the back buffer at the given position and color. + * The string is then blitted to the screen + */ +void Screen::print(const Common::Point &pt, int fgColor, int bgColor, const char *format, ...) { + // Create the string to display + char buffer[100]; + va_list args; + + va_start(args, format); + vsprintf(buffer, format, args); + va_end(args); + Common::String str(buffer); + + // Figure out area to draw text in + Common::Point pos = pt; + int width = stringWidth(str); + pos.y--; // Font is always drawing one line higher + if (!pos.x) + // Center text horizontally + pos.x = (SHERLOCK_SCREEN_WIDTH - width) / 2; + + Common::Rect textBounds(pos.x, pos.y, pos.x + width, pos.y + _fontHeight); + if (textBounds.right > SHERLOCK_SCREEN_WIDTH) + textBounds.moveTo(SHERLOCK_SCREEN_WIDTH - width, textBounds.top); + if (textBounds.bottom > SHERLOCK_SCREEN_HEIGHT) + textBounds.moveTo(textBounds.left, SHERLOCK_SCREEN_HEIGHT - _fontHeight); + + // Write out the string at the given position + writeString(str, Common::Point(textBounds.left, textBounds.top), fgColor); + + // Copy the affected area to the screen + slamRect(textBounds); +} + +/** + * Returns the width of a string in pixels + */ +int Screen::stringWidth(const Common::String &str) { + int width = 0; + + for (const char *c = str.c_str(); *c; ++c) + width += charWidth(*c); + + return width; +} + +/** + * Returns the width of a character in pixels + */ +int Screen::charWidth(char c) { + if (c == ' ') + return 5; + else if (c > ' ' && c <= '~') + return (*_font)[c - 33]._frame.w + 1; + else + return 0; +} + +/** + * Draws the given string into the back buffer using the images stored in _font + */ +void Screen::writeString(const Common::String &str, const Common::Point &pt, int color) { + Common::Point charPos = pt; + + for (const char *c = str.c_str(); *c; ++c) { + if (*c == ' ') + charPos.x += 5; + else { + assert(*c > ' ' && *c <= '~'); + ImageFrame &frame = (*_font)[*c - 33]; + _backBuffer.transBlitFrom(frame, charPos, false, color); + charPos.x += frame._frame.w + 1; + } + } + + addDirtyRect(Common::Rect(pt.x, pt.y, charPos.x, pt.y + _fontHeight)); +} + + } // End of namespace Sherlock diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 419ae681c2..257eb916b9 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -48,10 +48,14 @@ private: int _fontNumber; Common::List _dirtyRects; uint32 _transitionSeed; + ImageFile *_font; + int _fontHeight; void mergeDirtyRects(); bool unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2); + + void writeString(const Common::String &str, const Common::Point &pt, int color); protected: virtual void addDirtyRect(const Common::Rect &r); public: @@ -61,6 +65,7 @@ public: byte _sMap[PALETTE_SIZE]; public: Screen(SherlockEngine *vm); + ~Screen(); void setFont(int fontNumber); @@ -89,6 +94,10 @@ public: void flushImage(ImageFrame *frame, const Common::Point &pt, int16 *xp, int16 *yp, int16 *w, int16 *h); + + int stringWidth(const Common::String &str); + + int charWidth(char c); }; } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 1cd5b80980..1f201c74b8 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -431,7 +431,7 @@ void UserInterface::toggleButton(int num) { */ void UserInterface::clearInfo() { if (_infoFlag) { - _vm->_screen->fillRect(16, INFO_LINE, SHERLOCK_SCREEN_WIDTH - 200, INFO_LINE + 9, + _vm->_screen->fillRect(16, INFO_LINE, SHERLOCK_SCREEN_WIDTH - 20, INFO_LINE + 9, INFO_BLACK); _infoFlag = false; _oldLook = -1; -- cgit v1.2.3 From 97e58fb0171af885019d997493db33fab9af0091 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 24 Mar 2015 20:14:13 -0400 Subject: SHERLOCK: Fix display of scene hotspots --- engines/sherlock/screen.cpp | 11 ++++++++--- engines/sherlock/screen.h | 2 ++ engines/sherlock/user_interface.cpp | 7 ++++--- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index b1ad280b39..e0eab428a8 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -46,7 +46,7 @@ Screen::~Screen() { void Screen::setFont(int fontNumber) { _fontNumber = fontNumber; - Common::String fname = Common::String::format("FONT%d.VGS", fontNumber); + Common::String fname = Common::String::format("FONT%d.VGS", fontNumber + 1); // Discard any previous font and read in new one delete _font; @@ -372,9 +372,14 @@ void Screen::writeString(const Common::String &str, const Common::Point &pt, int charPos.x += frame._frame.w + 1; } } - - addDirtyRect(Common::Rect(pt.x, pt.y, charPos.x, pt.y + _fontHeight)); } +/** + * Fills an area on the back buffer, and then copies it to the screen + */ +void Screen::bar(const Common::Rect &r, int color) { + _backBuffer.fillRect(r, color); + slamRect(r); +} } // End of namespace Sherlock diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 257eb916b9..239067b1cc 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -98,6 +98,8 @@ public: int stringWidth(const Common::String &str); int charWidth(char c); + + void bar(const Common::Rect &r, int color); }; } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 1f201c74b8..661604e4bf 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -268,7 +268,8 @@ void UserInterface::handleInput() { // The mouse was clicked in the playing area with no action buttons down. // Check if the mouse was clicked in a script zone. If it was, // then execute the script. Otherwise, walk to the given position - if (scene.checkForZones(pt, SCRIPT_ZONE) != 0) { + if (scene.checkForZones(pt, SCRIPT_ZONE) != 0 || + scene.checkForZones(pt, NOWALK_ZONE) != 0) { // Mouse clicked in script zone events._pressed = events._released = false; } else { @@ -431,8 +432,8 @@ void UserInterface::toggleButton(int num) { */ void UserInterface::clearInfo() { if (_infoFlag) { - _vm->_screen->fillRect(16, INFO_LINE, SHERLOCK_SCREEN_WIDTH - 20, INFO_LINE + 9, - INFO_BLACK); + _vm->_screen->bar(Common::Rect(16, INFO_LINE, SHERLOCK_SCREEN_WIDTH - 20, + INFO_LINE + 9), INFO_BLACK); _infoFlag = false; _oldLook = -1; } -- cgit v1.2.3 From 03a969bd0f696f9a7fa0dc56c47c2b05d28a5a47 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 24 Mar 2015 22:24:45 -0400 Subject: SHERLOCK: Implementing walk code --- engines/sherlock/people.cpp | 127 ++++++++++++++++++++++++++++++++++-- engines/sherlock/people.h | 1 + engines/sherlock/scene.cpp | 56 ++++++++++++---- engines/sherlock/scene.h | 6 +- engines/sherlock/sherlock.cpp | 3 + engines/sherlock/user_interface.cpp | 6 ++ engines/sherlock/user_interface.h | 2 + 7 files changed, 185 insertions(+), 16 deletions(-) diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 8a8dcb5245..ca840bb5b1 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -58,6 +58,7 @@ People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) { _allowWalkAbort = false; _portraitLoaded = false; _clearingThePortrait = false; + _srcZone = _destZone = 0; } People::~People() { @@ -143,7 +144,7 @@ void People::setWalking() { // If the player is already close to the given destination that no // walking is needed, move to the next straight line segment in the // overall walking route, if there is one - for (;;) { + do { // Since we want the player to be centered on the destination they // clicked, but characters draw positions start at their left, move // the destination half the character width to draw him centered @@ -306,13 +307,131 @@ void People::gotoStand(Sprite &sprite) { _allowWalkAbort = true; } +/** + * Walk to the co-ordinates passed, and then face the given direction + */ void People::walkToCoords(const Common::Point &destPos, int destDir) { - // TODO - warning("TODO: walkToCoords"); + Events &events = *_vm->_events; + Scene &scene = *_vm->_scene; + Talk &talk = *_vm->_talk; + + CursorId oldCursor = events.getCursor(); + events.setCursor(WAIT); + + _walkDest = Common::Point(destPos.x / 100 + 10, destPos.y / 100); + _allowWalkAbort = true; + goAllTheWay(); + + // Keep calling doBgAnim until the walk is done + do { + events.pollEventsAndWait(); + scene.doBgAnim(); + } while (!_vm->shouldQuit() && _player._walkCount); + + if (!talk._talkToAbort) { + // Put player exactly on destination position, and set direction + _player._position = destPos; + _player._sequenceNumber = destDir; + gotoStand(_player); + + // Draw Holmes facing the new direction + scene.doBgAnim(); + + if (!talk._talkToAbort) + events.setCursor(oldCursor); + } } +/** + * Called to set the character walking to the current cursor location. + * It uses the zones and the inter-zone points to determine a series + * of steps to walk to get to that position. + */ void People::goAllTheWay() { - // TODO + Scene &scene = *_vm->_scene; + Common::Point srcPt(_player._position.x / 100 + _player.frameWidth() / 2, + _player._position.y / 100); + + // Get the zone the player is currently in + _srcZone = scene.whichZone(srcPt); + if (_srcZone == -1) + _srcZone = scene.closestZone(srcPt); + + // Get the zone of the destination + _destZone = scene.whichZone(_walkDest); + if (_destZone == -1) { + _destZone = scene.closestZone(_walkDest); + + // The destination isn't in a zone + if (_walkDest.x >= (SHERLOCK_SCREEN_WIDTH - 1)) + _walkDest.x = SHERLOCK_SCREEN_WIDTH - 2; + + // Trace a line between the centroid of the found closest zone to + // the destination, to find the point at which the zone will be left + const Common::Rect &destRect = scene._zones[_destZone]; + const Common::Point destCenter((destRect.left + destRect.right) / 2, + (destRect.top + destRect.bottom) / 2); + const Common::Point delta = _walkDest - destCenter; + Common::Point pt(destCenter.x * 100, destCenter.y * 100); + + // Move along the line until the zone is left + do { + pt += delta; + } while (destRect.contains(pt.x / 100, pt.y / 100)); + + // Set the new walk destination to the last point that was in the + // zone just before it was left + _walkDest = Common::Point((pt.x - delta.x * 2) / 100, + (pt.y - delta.y * 2) / 100); + } + + // Only do a walk if both zones are acceptable + if (_srcZone == -2 || _destZone == -2) + return; + + // If the start and dest zones are the same, walk directly to the dest point + if (_srcZone == _destZone) { + setWalking(); + } else { + // Otherwise a path needs to be formed from the path information + int i = scene._walkDirectory[_srcZone][_destZone]; + + // See if we need to use a reverse path + if (i == -1) + i = scene._walkDirectory[_destZone][_srcZone]; + + int count = scene._walkData[i]; + ++i; + + // See how many points there are between the src and dest zones + if (!count || count == 255) { + // There are none, so just walk to the new zone + setWalking(); + } else { + // There are points, so set up a multi-step path between points + // to reach the given destination + _walkTo.clear(); + + if (scene._walkDirectory[_srcZone][_destZone] != -1) { + for (int idx = 0; idx < count; ++idx, i += 3) { + _walkTo.push(Common::Point(READ_LE_UINT16(&scene._walkData[i]), + scene._walkData[i + 2])); + } + } else { + for (int idx = 0; idx < count; ++idx) + _walkTo.push(Common::Point()); + + for (int idx = count - 1; idx >= 0; --idx, i += 3) { + _walkTo[idx].x = READ_LE_UINT16(&scene._walkData[i]); + _walkTo[idx].y = scene._walkData[i + 2]; + } + } + + // Start walking + _walkDest = _walkTo.top(); + setWalking(); + } + } } } // End of namespace Sherlock diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index 8d1953ee20..0393528095 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -59,6 +59,7 @@ private: Sprite &_player; bool _walkLoaded; int _oldWalkSequence; + int _srcZone, _destZone; public: Common::Point _walkDest; Common::Stack _walkTo; diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 95e8355957..c5cba1b5cd 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -176,7 +176,7 @@ void Scene::freeScene() { _walkData.clear(); _cAnim.clear(); _bgShapes.clear(); - _bounds.clear(); + _zones.clear(); _canimShapes.clear(); for (uint idx = 0; idx < _images.size(); ++idx) @@ -205,8 +205,8 @@ bool Scene::loadScene(const Common::String &filename) { _ongoingCans = 0; // Reset the list of walkable areas - _bounds.clear(); - _bounds.push_back(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + _zones.clear(); + _zones.push_back(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); _descText.clear(); _comments = ""; @@ -311,12 +311,12 @@ bool Scene::loadScene(const Common::String &filename) { Common::SeekableReadStream *boundsStream = !_lzwMode ? rrmStream : decompressLZ(*rrmStream, size); - _bounds.resize(size / 10); - for (uint idx = 0; idx < _bounds.size(); ++idx) { - _bounds[idx].left = boundsStream->readSint16LE(); - _bounds[idx].top = boundsStream->readSint16LE(); - _bounds[idx].setWidth(boundsStream->readSint16LE()); - _bounds[idx].setHeight(boundsStream->readSint16LE()); + _zones.resize(size / 10); + for (uint idx = 0; idx < _zones.size(); ++idx) { + _zones[idx].left = boundsStream->readSint16LE(); + _zones[idx].top = boundsStream->readSint16LE(); + _zones[idx].setWidth(boundsStream->readSint16LE()); + _zones[idx].setHeight(boundsStream->readSint16LE()); boundsStream->skip(2); // Skip unused scene number field } @@ -328,8 +328,8 @@ bool Scene::loadScene(const Common::String &filename) { error("Invalid scene path data"); // Load the walk directory - for (uint idx1 = 0; idx1 < _bounds.size(); ++idx1) { - for (uint idx2 = 0; idx2 < _bounds.size(); ++idx2) + for (uint idx1 = 0; idx1 < _zones.size(); ++idx1) { + for (uint idx2 = 0; idx2 < _zones.size(); ++idx2) _walkDirectory[idx1][idx2] = rrmStream->readSint16LE(); } @@ -1450,4 +1450,38 @@ int Scene::checkForZones(const Common::Point &pt, int zoneType) { return matches; } +/** + * Check which zone the the given position is located in. + */ +int Scene::whichZone(const Common::Point &pt) { + for (uint idx = 0; idx < _zones.size(); ++idx) { + if (_zones[idx].contains(pt)) + return idx; + } + + return -1; +} + +/** + * Returns the index of the closest zone to a given point. + */ +int Scene::closestZone(const Common::Point &pt) { + int dist = 1000; + int zone = -1; + + for (uint idx = 0; idx < _zones.size(); ++idx) { + Common::Point zc((_zones[idx].left + _zones[idx].right) / 2, + (_zones[idx].top + _zones[idx].bottom) / 2); + int d = ABS(zc.x - pt.x) + ABS(zc.y - pt.y); + + if (d < dist) { + // Found a closer zone + dist = d; + zone = idx; + } + } + + return zone; +} + } // End of namespace Sherlock diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 1a9fe7b02c..1b3a730179 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -137,7 +137,7 @@ public: int _invGraphicItems; Common::String _comments; Common::Array _descText; - Common::Array _bounds; + Common::Array _zones; Common::Array _bgShapes; Common::Array _cAnim; Common::Array _sequenceBuffer; @@ -179,6 +179,10 @@ public: int findBgShape(const Common::Rect &r); int checkForZones(const Common::Point &pt, int zoneType); + + int whichZone(const Common::Point &pt); + + int closestZone(const Common::Point &pt); }; } // End of namespace Sherlock diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index a9de32972f..107dee5a41 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -100,6 +100,9 @@ Common::Error SherlockEngine::run() { if (shouldQuit()) break; + // Reset UI flags + _ui->reset(); + // Reset the active characters to initially just Sherlock _people->reset(); diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 661604e4bf..fc94cc5a5c 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -82,6 +82,12 @@ UserInterface::~UserInterface() { delete _controls; } +void UserInterface::reset() { + _oldKey = -1; + _help = _oldHelp = -1; + _oldTemp = _temp = -1; +} + /** * Main input handler for the user interface */ diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index d312ff919c..d2ef8942c3 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -95,6 +95,8 @@ public: UserInterface(SherlockEngine *vm); ~UserInterface(); + void reset(); + void handleInput(); void clearInfo(); -- cgit v1.2.3 From fc7f8024beb4e3a0ee2b6def649ca1a3e91fa899 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 25 Mar 2015 08:16:59 -0400 Subject: SHERLOCK: Fixes to scene loading --- engines/sherlock/objects.cpp | 8 ++++---- engines/sherlock/scene.cpp | 8 +++++++- engines/sherlock/screen.cpp | 20 ++++++++++++-------- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index e0a24c5b7d..cdd397f23c 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -381,10 +381,10 @@ void UseType::synchronize(Common::SeekableReadStream &s) { _names[idx] = Common::String(buffer); } - _useFlag = s.readUint16LE(); - _dFlag[0] = s.readUint16LE(); - _lFlag[0] = s.readUint16LE(); - _lFlag[1] = s.readUint16LE(); + _useFlag = s.readSint16LE(); + _dFlag[0] = s.readSint16LE(); + _lFlag[0] = s.readSint16LE(); + _lFlag[1] = s.readSint16LE(); s.read(buffer, 12); _target = Common::String(buffer); diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index c5cba1b5cd..1b7a1a9cd2 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -601,7 +601,13 @@ void Scene::transitionToScene() { } else { // It's canimation information cAnimNum = _hsavedFs - 101; + } + + // Reset positioning for next load + _hsavedPos = Common::Point(-1, -1); + _hsavedFs = -1; + if (cAnimNum != -1) { // Prevent Holmes from being drawn people[PLAYER]._position = Common::Point(0, 0); } @@ -1166,7 +1172,7 @@ void Scene::doBgAnim() { else if (people[AL]._type == REMOVE) screen._backBuffer.blitFrom(screen._backBuffer2, pt, bounds); - for (uint idx = 0; _bgShapes.size(); ++idx) { + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if (o._type == ACTIVE_BG_SHAPE || o._type == HIDE_SHAPE || o._type == REMOVE) screen.restoreBackground(bounds); diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index e0eab428a8..7c222f3e24 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -246,11 +246,13 @@ void Screen::verticalTransition() { * Copies a section of the second back buffer into the main back buffer */ void Screen::restoreBackground(const Common::Rect &r) { - Common::Rect tempRect = r; - tempRect.clip(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); + if (r.width() > 0 && r.height() > 0) { + Common::Rect tempRect = r; + tempRect.clip(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); - if (tempRect.isValidRect()) - _backBuffer.blitFrom(_backBuffer2, Common::Point(tempRect.left, tempRect.top), tempRect); + if (tempRect.isValidRect()) + _backBuffer.blitFrom(_backBuffer2, Common::Point(tempRect.left, tempRect.top), tempRect); + } } /** @@ -264,11 +266,13 @@ void Screen::slamArea(int16 xp, int16 yp, int16 w, int16 h) { * Copies a given area to the screen */ void Screen::slamRect(const Common::Rect &r) { - Common::Rect tempRect = r; - tempRect.clip(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + if (r.width() && r.height() > 0) { + Common::Rect tempRect = r; + tempRect.clip(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); - if (tempRect.isValidRect()) - blitFrom(_backBuffer, Common::Point(tempRect.left, tempRect.top), tempRect); + if (tempRect.isValidRect()) + blitFrom(_backBuffer, Common::Point(tempRect.left, tempRect.top), tempRect); + } } /** -- cgit v1.2.3 From b280d72ab8de6f6fe77d0957de1b651b9fdb264c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 25 Mar 2015 22:23:53 -0400 Subject: SHERLOCK: Sprite positioning fixes --- engines/sherlock/objects.cpp | 2 +- engines/sherlock/scene.cpp | 5 ++++- engines/sherlock/screen.cpp | 8 ++++++-- engines/sherlock/user_interface.cpp | 6 +++--- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index cdd397f23c..7e72eff1e9 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -613,7 +613,7 @@ void Object::checkObject(Object &o) { if (pt.y > 128) pt.y = (pt.y - 128) * -1; else - pt.y; + pt.y--; _delta = pt; _frameNumber += 2; diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 1b7a1a9cd2..b00e07a8a7 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -1330,7 +1330,8 @@ void Scene::doBgAnim() { )); } else { screen.flushImage(people[AL]._imageFrame, - Common::Point(people[AL]._position.x / 100, people[AL]._position.y / 100), + Common::Point(people[AL]._position.x / 100, + people[AL]._position.y / 100 - people[AL].frameHeight()), &people[AL]._oldPosition.x, &people[AL]._oldPosition.y, &people[AL]._oldSize.x, &people[AL]._oldSize.y); } @@ -1370,8 +1371,10 @@ void Scene::doBgAnim() { screen.slamArea(o._position.x, o._position.y, o._oldSize.x, o._oldSize.y); screen.slamArea(o._oldPosition.x, o._oldPosition.y, o._oldSize.x, o._oldSize.y); } else if (o._type == HIDE_SHAPE) { + // Hiding shape, so flush it out and mark it as hidden screen.flushImage(o._imageFrame, o._position, &o._oldPosition.x, &o._oldPosition.y, &o._oldSize.x, &o._oldSize.y); + o._type = HIDDEN; } } } diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 7c222f3e24..098d43e827 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -287,8 +287,12 @@ void Screen::flushImage(ImageFrame *frame, const Common::Point &pt, // See if the areas of the old and new overlap, and if so combine the areas if (newBounds.intersects(oldBounds)) { - newBounds.extend(oldBounds); - slamRect(newBounds); + Common::Rect mergedBounds = newBounds; + mergedBounds.extend(oldBounds); + mergedBounds.right += 1; + mergedBounds.bottom += 1; + + slamRect(mergedBounds); } else { // The two areas are independent, so copy them both slamRect(newBounds); diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index fc94cc5a5c..b0ac0b169b 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -176,7 +176,7 @@ void UserInterface::handleInput() { _help = _oldHelp; } - if (_bgFound != _oldBgFound) { + if (_bgFound != _oldBgFound || _oldBgFound == -1) { _infoFlag = true; clearInfo(); @@ -438,8 +438,8 @@ void UserInterface::toggleButton(int num) { */ void UserInterface::clearInfo() { if (_infoFlag) { - _vm->_screen->bar(Common::Rect(16, INFO_LINE, SHERLOCK_SCREEN_WIDTH - 20, - INFO_LINE + 9), INFO_BLACK); + _vm->_screen->bar(Common::Rect(16, INFO_LINE, SHERLOCK_SCREEN_WIDTH - 19, + INFO_LINE + 10), INFO_BLACK); _infoFlag = false; _oldLook = -1; } -- cgit v1.2.3 From 94d79c0ed36269fe1c7bbf08871329d166acc2f0 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 25 Mar 2015 22:41:42 -0400 Subject: SHERLOCK: Fix restoring background before drawing new sprites --- engines/sherlock/scene.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index b00e07a8a7..0cb6d7721b 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -1175,7 +1175,7 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if (o._type == ACTIVE_BG_SHAPE || o._type == HIDE_SHAPE || o._type == REMOVE) - screen.restoreBackground(bounds); + screen.restoreBackground(o.getOldBounds()); } if (people._portraitLoaded) -- cgit v1.2.3 From a8350c48e93143dd2d6344efce1b36c4e2eb34be Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 25 Mar 2015 22:56:56 -0400 Subject: SHERLOCK: Fix display of hotspot tooltips --- engines/sherlock/user_interface.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index b0ac0b169b..bcf460a821 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -173,7 +173,7 @@ void UserInterface::handleInput() { if (_help != -1) depressButton(_help); - _help = _oldHelp; + _oldHelp = _help; } if (_bgFound != _oldBgFound || _oldBgFound == -1) { @@ -185,6 +185,8 @@ void UserInterface::handleInput() { screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, INFO_BACKGROUND, "%s", scene._bgShapes[_bgFound]._description); + + _oldBgFound = _bgFound; } } else { // We're not in STD_MODE -- cgit v1.2.3 From 0f52dcc561fbe05816452d2a20b3f09f6cd9e0fa Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 25 Mar 2015 23:07:56 -0400 Subject: SHERLOCK: Highlight default action button when highlighting hotspots --- engines/sherlock/user_interface.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index bcf460a821..df3ac9352c 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -371,8 +371,7 @@ void UserInterface::restoreButton(int num) { screen._backBuffer.blitFrom(screen._backBuffer2, pt, Common::Rect(pt.x, pt.y, pt.x + 90, pt.y + 19)); - screen._backBuffer.blitFrom(screen._backBuffer, pt, - Common::Rect(pt.x, pt.y, pt.x + frame.w, pt.y + frame.h)); + screen.slamArea(pt.x, pt.y, pt.x + frame.w, pt.y + frame.h); if (!_menuCounter) { _infoFlag++; -- cgit v1.2.3 From 5e45abcca4b76955cc0ebcfa54a1b9f9be12bfa0 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 26 Mar 2015 21:40:24 -0400 Subject: SHERLOCK: Implemented printObjectDesc --- engines/sherlock/inventory.cpp | 6 +- engines/sherlock/inventory.h | 4 +- engines/sherlock/objects.cpp | 10 +- engines/sherlock/objects.h | 6 +- engines/sherlock/scene.cpp | 53 +------- engines/sherlock/scene.h | 6 +- engines/sherlock/screen.cpp | 22 +++- engines/sherlock/screen.h | 16 ++- engines/sherlock/user_interface.cpp | 252 +++++++++++++++++++++++++++++++++++- engines/sherlock/user_interface.h | 16 +++ 10 files changed, 316 insertions(+), 75 deletions(-) diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index 2a277a6331..e103213eb5 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -36,7 +36,7 @@ Inventory::~Inventory() { freeGraphics(); } -void Inventory::freeInventory() { +void Inventory::freeInv() { freeGraphics(); _names.clear(); @@ -116,4 +116,8 @@ int Inventory::findInv(const Common::String &name) { return result; } +void Inventory::putInv(int slamit) { + // TODO +} + } // End of namespace Sherlock diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index e561f0318a..01a325e382 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -54,13 +54,15 @@ public: Inventory(SherlockEngine *vm); ~Inventory(); - void freeInventory(); + void freeInv(); void loadInv(); void loadGraphics(); int findInv(const Common::String &name); + + void putInv(int slamit); }; } // End of namespace Sherlock diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 7e72eff1e9..39a9cf8014 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -404,11 +404,11 @@ void Object::setVm(SherlockEngine *vm) { * Load the object data from the passed stream */ void Object::synchronize(Common::SeekableReadStream &s) { - char buffer[12]; + char buffer[41]; s.read(buffer, 12); _name = Common::String(buffer); - - s.read(_description, 41); + s.read(buffer, 41); + _description = Common::String(buffer); _examine.clear(); _sequences = nullptr; @@ -851,14 +851,14 @@ int Object::checkNameForCodes(const Common::String &name, Common::StringArray *m int messageNum = atoi(name.c_str() + 1); ui._infoFlag++; ui.clearInfo(); - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, INFO_BACKGROUND, + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, (*messages)[messageNum].c_str()); ui._menuCounter = 25; } else if (name.hasPrefix("@")) { // Message attached to canimation ui._infoFlag++; ui.clearInfo(); - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, INFO_BACKGROUND, + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", name.c_str() + 1); printed = true; ui._menuCounter = 25; diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 4944681ab3..26ad1d3900 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -123,8 +123,8 @@ public: }; struct ActionType { - char _cAnimNum; - char _cAnimSpeed; // if high bit set, play in reverse + int8 _cAnimNum; + uint8 _cAnimSpeed; // if high bit set, play in reverse Common::String _names[4]; void synchronize(Common::SeekableReadStream &s); @@ -155,7 +155,7 @@ public: static void setVm(SherlockEngine *vm); public: Common::String _name; // Name - char _description[41]; // Description lines + Common::String _description; // Description lines Common::String _examine; // Examine in-depth description int _sequenceOffset; uint8 *_sequences; // Holds animation sequences diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 0cb6d7721b..6442538794 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -162,7 +162,7 @@ void Scene::selectScene() { */ void Scene::freeScene() { _vm->_talk->freeTalkVars(); - _vm->_inventory->freeInventory(); + _vm->_inventory->freeInv(); _vm->_sound->freeSong(); _vm->_sound->freeLoadedSounds(); @@ -849,6 +849,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) { People &people = *_vm->_people; Resources &res = *_vm->_res; Talk &talk = *_vm->_talk; + UserInterface &ui = *_vm->_ui; Common::Point tpPos, walkPos; int tpDir, walkDir; int tFrames = 0; @@ -993,7 +994,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) { while (--frames) { if (frames == pauseFrame) - printObjDesc(_cAnimStr, true); + ui.printObjectDesc(); doBgAnim(); @@ -1048,54 +1049,6 @@ int Scene::startCAnim(int cAnimNum, int playRate) { return 1; } -/** - * Print the description of an object - */ -void Scene::printObjDesc(const Common::String &str, bool firstTime) { - /* TODO - - Events &events = *_vm->_events; - Screen &screen = *_vm->_screen; - Talk &talk = *_vm->_talk; - int savedSelector; - - if (str.hasPrefix("_")) { - _lookScriptFlag = true; - events.setCursor(MAGNIFY); - savedSelector = _selector; - talk.talkTo(str.c_str() + 1); - _lookScriptFlag = false; - - if (talk._talkToAbort) { - events.setCursor(ARROW); - return; - } - - // Check if looking at an inventory object - if (!_invLookFlag) { - // See if this look was called by a right button click or not - if (!_lookHelp) { - // If it wasn't a right button click, then we need depress - // the look button before we close the window. So save a copy of the - // menu area, and draw the controls onto it - Surface tempSurface((*_controls)[0]._frame->w, (*_controls)[0]._frame->h); - tempSurface.blitFrom(screen._backBuffer2, Common::Point(0, 0), - Common::Rect(MENU_POINTS[0][0], MENU_POINTS[0][1], - MENU_POINTS[0][0] + tempSurface.w, MENU_POINTS[0][1] + tempSurface.h)); - screen._backBuffer2.transBlitFrom((*_controls)[0]._frame, - Common::Point(MENU_POINTS[0][0], MENU_POINTS[0][1])); - - banishWindow(1); - events.setCursor(MAGNIFY); - - } - } - } - - // TODO - */ -} - /** * Animate all objects and people. */ diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 1b3a730179..27313e34af 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -96,10 +96,7 @@ class Scene { private: SherlockEngine *_vm; Common::String _rrmName; - int _cAnimFramePause; - Common::String _cAnimStr; InvMode _invMode; - bool _lookScriptFlag; int _selector; bool _invLookFlag; bool _lookHelp; @@ -154,6 +151,7 @@ public: int _animating; bool _doBgAnimDone; int _tempFadeStyle; + int _cAnimFramePause; public: Scene(SherlockEngine *vm); ~Scene(); @@ -166,8 +164,6 @@ public: Exit *checkForExit(const Common::Rect &r); - void printObjDesc(const Common::String &str, bool firstTime); - int startCAnim(int cAnimNum, int playRate); int toggleObject(const Common::String &name); diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 098d43e827..646802094f 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -309,7 +309,7 @@ void Screen::flushImage(ImageFrame *frame, const Common::Point &pt, * Prints the text passed onto the back buffer at the given position and color. * The string is then blitted to the screen */ -void Screen::print(const Common::Point &pt, int fgColor, int bgColor, const char *format, ...) { +void Screen::print(const Common::Point &pt, int color, const char *format, ...) { // Create the string to display char buffer[100]; va_list args; @@ -334,12 +334,30 @@ void Screen::print(const Common::Point &pt, int fgColor, int bgColor, const char textBounds.moveTo(textBounds.left, SHERLOCK_SCREEN_HEIGHT - _fontHeight); // Write out the string at the given position - writeString(str, Common::Point(textBounds.left, textBounds.top), fgColor); + writeString(str, Common::Point(textBounds.left, textBounds.top), color); // Copy the affected area to the screen slamRect(textBounds); } +/** + * Print a strings onto the back buffer without blitting it to the screen + */ +void Screen::gPrint(const Common::Point &pt, int color, const char *format, ...) { + // Create the string to display + char buffer[100]; + va_list args; + + va_start(args, format); + vsprintf(buffer, format, args); + va_end(args); + Common::String str(buffer); + + // Print the text + writeString(str, pt, color); +} + + /** * Returns the width of a string in pixels */ diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 239067b1cc..45a50e7e85 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -35,10 +35,15 @@ namespace Sherlock { #define PALETTE_COUNT 256 #define VGA_COLOR_TRANS(x) ((x) * 255 / 63) -#define INFO_BLACK 1 -#define INFO_FOREGROUND 11 -#define INFO_BACKGROUND 1 - +enum { + INFO_BLACK = 1, + INFO_FOREGROUND = 11, + INFO_BACKGROUND = 1, + BORDER_COLOR = 237, + INV_FOREGROUND = 14, + INV_BACKGROUND = 1, + COM_FOREGROUND = 15 +}; class SherlockEngine; @@ -85,7 +90,8 @@ public: void verticalTransition(); - void print(const Common::Point &pt, int fgColor, int bgColor, const char *format, ...); + void print(const Common::Point &pt, int color, const char *format, ...); + void gPrint(const Common::Point &pt, int color, const char *format, ...); void restoreBackground(const Common::Rect &r); diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index df3ac9352c..b0388b4e29 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -54,6 +54,8 @@ const int INVENTORY_POINTS[8][3] = { }; const char COMMANDS[13] = "LMTPOCIUGJFS"; +const char *const PRESS_KEY_FOR_MORE = "Press any Key for More."; +const char *const PRESS_KEY_TO_CONTINUE = "Press any Key to Continue."; /*----------------------------------------------------------------*/ @@ -74,6 +76,11 @@ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { _keyboardInput = false; _invMode = 0; _pause = false; + _cNum = 0; + _selector = _oldSelector = -1; + _windowBounds = Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH - 1, + SHERLOCK_SCREEN_HEIGHT - 1); + _windowStyle = 0; _controls = new ImageFile("menu.all"); } @@ -183,8 +190,7 @@ void UserInterface::handleInput() { if (_help != -1 && (scene._bgShapes[_bgFound]._description[0] != 32 && scene._bgShapes[_bgFound]._description[0])) screen.print(Common::Point(0, INFO_LINE + 1), - INFO_FOREGROUND, INFO_BACKGROUND, "%s", - scene._bgShapes[_bgFound]._description); + INFO_FOREGROUND, scene._bgShapes[_bgFound]._description.c_str()); _oldBgFound = _bgFound; } @@ -457,8 +463,53 @@ void UserInterface::whileMenuCounter() { } } +/** + * Creates a text window and uses it to display the in-depth description + * of the highlighted object + */ void UserInterface::examine() { - // TODO + Events &events = *_vm->_events; + Inventory &inv = *_vm->_inventory; + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + Talk &talk = *_vm->_talk; + Common::Point pt = events.mousePos(); + int canimSpeed; + + if (pt.y < (CONTROLS_Y + 9)) { + Object &obj = scene._bgShapes[_bgFound]; + + if (obj._lookcAnim != 0) { + canimSpeed = ((obj._lookcAnim & 0xe0) >> 5) + 1; + scene._cAnimFramePause = obj._lookFrames; + _cAnimStr = obj._examine; + _cNum = (obj._lookcAnim & 0x1f) - 1; + + scene.startCAnim(_cNum, canimSpeed); + } else if (obj._lookPosition.y != 0) { + // Need to walk to the object to be examined + people.walkToCoords(obj._lookPosition, obj._lookFacing); + } + + if (talk._talkToAbort) { + _cAnimStr = obj._examine; + if (obj._lookFlag) + _vm->setFlags(obj._lookFlag); + } + } else { + // Looking at an inventory item + _cAnimStr = inv[_selector]._examine; + if (inv[_selector]._lookFlag) + _vm->setFlags(inv[_selector]._lookFlag); + } + + if (!talk._talkToAbort) { + if (!scene._cAnimFramePause) + printObjectDesc(_cAnimStr, true); + else + // description was already printed in startCAnimation + scene._cAnimFramePause = 0; + } } void UserInterface::lookScreen(const Common::Point &pt) { @@ -497,4 +548,199 @@ void UserInterface::doTalkControl() { // TODO } + +/** +* Print the description of an object +*/ +void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { + Events &events = *_vm->_events; + Inventory &inv = *_vm->_inventory; + Screen &screen = *_vm->_screen; + Talk &talk = *_vm->_talk; + int savedSelector; + + if (str.hasPrefix("_")) { + _lookScriptFlag = true; + events.setCursor(MAGNIFY); + savedSelector = _selector; + talk.talkTo(str.c_str() + 1); + _lookScriptFlag = false; + + if (talk._talkToAbort) { + events.setCursor(ARROW); + return; + } + + // Check if looking at an inventory object + if (!_invLookFlag) { + // See if this look was called by a right button click or not + if (!_lookHelp) { + // If it wasn't a right button click, then we need depress + // the look button before we close the window. So save a copy of the + // menu area, and draw the controls onto it + Surface tempSurface((*_controls)[0]._frame.w, (*_controls)[0]._frame.h); + Common::Point pt(MENU_POINTS[0][0], MENU_POINTS[0][1]); + + tempSurface.blitFrom(screen._backBuffer2, Common::Point(0, 0), + Common::Rect(pt.x, pt.y, pt.x + tempSurface.w, pt.y + tempSurface.h)); + screen._backBuffer2.transBlitFrom((*_controls)[0]._frame, pt); + + banishWindow(1); + events.setCursor(MAGNIFY); + _windowBounds.top = CONTROLS_Y1; + _key = _oldKey = COMMANDS[LOOK_MODE - 1]; + _temp = _oldTemp = 0; + _menuMode = LOOK_MODE; + events.clearEvents(); + + screen._backBuffer2.blitFrom(tempSurface, pt); + } else { + events.setCursor(ARROW); + banishWindow(true); + _windowBounds.top = CONTROLS_Y1; + _key = _oldKey = -1; + _temp = _oldTemp = 0; + _menuMode = STD_MODE; + _lookHelp = 0; + events.clearEvents(); + } + } else { + // Looking at an inventory object + _selector = _oldSelector = savedSelector; + + // Reload the inventory graphics and draw the inventory + inv.loadInv(); + inv.putInv(2); + inv.freeInv(); + banishWindow(1); + + _windowBounds.top = CONTROLS_Y1; + _key = _oldKey = COMMANDS[INV_MODE - 1]; + _temp = _oldTemp = 0; + events.clearEvents(); + + _invLookFlag = 0; + _menuMode = INV_MODE; + _windowOpen = true; + } + + return; + } + + if (firstTime) { + // Only draw the border on the first call + _infoFlag = true; + clearInfo(); + + screen.bar(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, + CONTROLS_Y1 + 10), BORDER_COLOR); + screen.bar(Common::Rect(0, CONTROLS_Y + 10, 1, SHERLOCK_SCREEN_HEIGHT - 1), + BORDER_COLOR); + screen.bar(Common::Rect(SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y + 10, + SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); + screen.bar(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - 1, SHERLOCK_SCREEN_WIDTH, + SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); + } + + // Clear background + screen.bar(Common::Rect(2, CONTROLS_Y + 10, SHERLOCK_SCREEN_WIDTH - 2, + SHERLOCK_SCREEN_HEIGHT - 2), INV_BACKGROUND); + + _windowBounds.top = CONTROLS_Y; + events.clearEvents(); + + bool endOfStr = false; + const char *msgP = str.c_str(); + for (int lineNum = 0; lineNum < 5 && !endOfStr; ++lineNum) { + int width = 0; + const char *lineStartP = msgP; + + // Determine how much can be displayed on the line + do { + width += screen.charWidth(*msgP++); + } while (width < 300 && *msgP); + + if (*msgP) + --msgP; + else + endOfStr = true; + + // If the line needs to be wrapped, scan backwards to find + // the end of the previous word as a splitting point + if (width >= 300) { + while (*msgP != ' ') + --msgP; + endOfStr = false; + } + + // Print out the line + Common::String line(lineStartP, msgP); + screen.gPrint(Common::Point(16, CONTROLS_Y + 12 + lineNum * 9), + INV_FOREGROUND, line.c_str()); + } + + // Handle display depending on whether all the message was shown + if (!endOfStr) { + makeButton(Common::Rect(46, CONTROLS_Y, 272, CONTROLS_Y + 10), + (SHERLOCK_SCREEN_WIDTH - screen.stringWidth(PRESS_KEY_FOR_MORE)) / 2, + PRESS_KEY_FOR_MORE); + screen.gPrint(Common::Point((SHERLOCK_SCREEN_WIDTH - + screen.stringWidth(PRESS_KEY_FOR_MORE)) / 2, CONTROLS_Y), + COM_FOREGROUND, "P"); + _descStr = msgP; + } else { + makeButton(Common::Rect(46, CONTROLS_Y, 272, CONTROLS_Y + 10), + (SHERLOCK_SCREEN_WIDTH - screen.stringWidth(PRESS_KEY_TO_CONTINUE)) / 2, + PRESS_KEY_FOR_MORE); + screen.gPrint(Common::Point((SHERLOCK_SCREEN_WIDTH - + screen.stringWidth(PRESS_KEY_TO_CONTINUE)) / 2, CONTROLS_Y), + COM_FOREGROUND, "P"); + _descStr = ""; + } + + if (firstTime) { + if (!_windowStyle) { + screen.slamRect(Common::Rect(0, CONTROLS_Y, + SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + } + else { + Surface tempSurface(SHERLOCK_SCREEN_WIDTH, + (SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y) + 10); + Common::Rect r(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + + tempSurface.blitFrom(screen._backBuffer, Common::Point(0, CONTROLS_Y), r); + screen._backBuffer.blitFrom(screen._backBuffer2, + Common::Point(0, CONTROLS_Y), r); + + summonWindow(); + } + + _selector = _oldSelector = -1; + _windowOpen = true; + } else { + screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, + SHERLOCK_SCREEN_HEIGHT)); + } +} + +/** +* Print the previously selected object's decription +*/ +void UserInterface::printObjectDesc() { + printObjectDesc(_cAnimStr, true); +} + +void UserInterface::banishWindow(bool flag) { + // TODO +} + +void UserInterface::makeButton(const Common::Rect &bounds, int textX, + const Common::String &str) { + // TODO +} + +void UserInterface::summonWindow() { + // TODO +} + } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index d2ef8942c3..98f6cd21ea 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -64,6 +64,13 @@ private: bool _keyboardInput; int _invMode; bool _pause; + int _cNum; + int _selector, _oldSelector; + Common::String _cAnimStr; + bool _lookScriptFlag; + Common::Rect _windowBounds; + Common::String _descStr; + int _windowStyle; private: void depressButton(int num); @@ -86,6 +93,12 @@ private: void doMiscControl(int allowed); void doPickControl(); void doTalkControl(); + + void banishWindow(bool flag); + + void makeButton(const Common::Rect &bounds, int textX, const Common::String &str); + + void summonWindow(); public: MenuMode _menuMode; int _menuCounter; @@ -102,6 +115,9 @@ public: void clearInfo(); void whileMenuCounter(); + + void printObjectDesc(const Common::String &str, bool firstTime); + void printObjectDesc(); }; } // End of namespace Sherlock -- cgit v1.2.3 From 9f21575c564cb1aff07f0265a47af59ce31ec93e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 26 Mar 2015 23:10:10 -0400 Subject: SHERLOCK: Implemented banishWindow --- engines/sherlock/user_interface.cpp | 97 ++++++++++++++++++++++++++++++++++--- engines/sherlock/user_interface.h | 8 +-- 2 files changed, 94 insertions(+), 11 deletions(-) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index b0388b4e29..8e5cbb68ef 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -649,6 +649,7 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { _windowBounds.top = CONTROLS_Y; events.clearEvents(); + // Loop through displaying up to five lines bool endOfStr = false; const char *msgP = str.c_str(); for (int lineNum = 0; lineNum < 5 && !endOfStr; ++lineNum) { @@ -712,7 +713,8 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { screen._backBuffer.blitFrom(screen._backBuffer2, Common::Point(0, CONTROLS_Y), r); - summonWindow(); + // Display the window + summonWindow(tempSurface); } _selector = _oldSelector = -1; @@ -730,17 +732,98 @@ void UserInterface::printObjectDesc() { printObjectDesc(_cAnimStr, true); } -void UserInterface::banishWindow(bool flag) { - // TODO -} - void UserInterface::makeButton(const Common::Rect &bounds, int textX, const Common::String &str) { // TODO } -void UserInterface::summonWindow() { - // TODO +/** + * Displays a passed window by gradually displaying it up vertically + */ +void UserInterface::summonWindow(const Surface &bgSurface) { + Events &events = *_vm->_events; + Screen &screen = *_vm->_screen; + + if (_windowOpen) + // A window is already open, so can't open another one + return; + + // Gradually slide up the display of the window + for (int idx = 1; idx <= (SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y); idx += 2) { + screen.blitFrom(bgSurface, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - idx), + Common::Rect(0, 0, bgSurface.w, idx)); + screen.slamRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - idx, + SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + + events.delay(10); + } + + // Final display of the entire window + screen._backBuffer.blitFrom(bgSurface, Common::Point(0, CONTROLS_Y), + Common::Rect(0, 0, bgSurface.w, bgSurface.h)); + screen.slamArea(0, CONTROLS_Y, bgSurface.w, bgSurface.h); + + _windowOpen = true; +} + +/** + * Close a currently open window + * @param flag 0 = slide old window down, 1 = slide old window up + */ +void UserInterface::banishWindow(bool flag) { + Events &events = *_vm->_events; + Screen &screen = *_vm->_screen; + + if (_windowOpen) { + if (!flag || !_windowStyle) { + // Slide window up + // Only slide the window up if the window style allows it + if (_windowStyle) { + for (int idx = 2; idx < (SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y); idx += 2) { + byte *pSrc = (byte *)screen._backBuffer.getBasePtr(0, CONTROLS_Y); + Common::copy(pSrc, pSrc + (SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y + idx) + * SHERLOCK_SCREEN_WIDTH, pSrc - SHERLOCK_SCREEN_WIDTH * 2); + screen._backBuffer.blitFrom(screen._backBuffer2, + Common::Point(0, CONTROLS_Y), + Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_HEIGHT, CONTROLS_Y + idx)); + + screen.slamArea(0, CONTROLS_Y + idx - 2, SHERLOCK_SCREEN_WIDTH, + SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y - idx + 2); + events.delay(10); + } + + // Restore final two old lines + screen._backBuffer.blitFrom(screen._backBuffer2, + Common::Point(0, SHERLOCK_SCREEN_HEIGHT - 2), + Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - 2, + SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + screen.slamArea(0, SHERLOCK_SCREEN_HEIGHT - 2, SHERLOCK_SCREEN_WIDTH, 2); + } else { + // Restore old area to completely erase window + screen._backBuffer.blitFrom(screen._backBuffer2, + Common::Point(0, CONTROLS_Y), + Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, + SHERLOCK_SCREEN_HEIGHT)); + } + } else { + for (int idx = SHERLOCK_SCREEN_HEIGHT - 1 - CONTROLS_Y1; idx >= 0; idx -= 2) { + byte *pSrc = (byte *)screen._backBuffer.getBasePtr(0, CONTROLS_Y1 + idx); + byte *pDest = (byte *)screen._backBuffer.getBasePtr(0, CONTROLS_Y1); + + Common::copy(pSrc, pSrc + (SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y1 - idx) + * SHERLOCK_SCREEN_WIDTH, pDest); + screen.slamArea(0, CONTROLS_Y1 + idx, SHERLOCK_SCREEN_WIDTH, + SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y1 - idx); + events.delay(10); + } + } + + _infoFlag = false; + _windowOpen = false; + } + + _menuMode = STD_MODE; } } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index 98f6cd21ea..291aa1e9d2 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -25,6 +25,7 @@ #include "common/scummsys.h" #include "common/events.h" +#include "sherlock/graphics.h" #include "sherlock/resources.h" namespace Sherlock { @@ -94,11 +95,7 @@ private: void doPickControl(); void doTalkControl(); - void banishWindow(bool flag); - void makeButton(const Common::Rect &bounds, int textX, const Common::String &str); - - void summonWindow(); public: MenuMode _menuMode; int _menuCounter; @@ -118,6 +115,9 @@ public: void printObjectDesc(const Common::String &str, bool firstTime); void printObjectDesc(); + + void summonWindow(const Surface &bgSurface); + void banishWindow(bool flag); }; } // End of namespace Sherlock -- cgit v1.2.3 From 4fad808aad87bc15827eed180f395c04c260e447 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 27 Mar 2015 08:36:04 -0400 Subject: SHERLOCK: Implemented doMainControl --- engines/sherlock/events.cpp | 8 ++ engines/sherlock/events.h | 1 + engines/sherlock/inventory.cpp | 4 + engines/sherlock/inventory.h | 2 + engines/sherlock/user_interface.cpp | 191 +++++++++++++++++++++++++++++++++++- engines/sherlock/user_interface.h | 4 + 6 files changed, 208 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index a6b3c899cb..5c94b7e1ff 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -191,6 +191,14 @@ void Events::clearEvents() { _oldButtons = _oldRightButton = false; } +/** + * Clear any pending keyboard inputs + */ +void Events::clearKeyboard() { + _pendingKeys.clear(); +} + + /** * Delay for a given number of game frames, where each frame is 1/60th of a second */ diff --git a/engines/sherlock/events.h b/engines/sherlock/events.h index 1c5fbc5be4..c3bdaf5a93 100644 --- a/engines/sherlock/events.h +++ b/engines/sherlock/events.h @@ -85,6 +85,7 @@ public: Common::KeyState getKey() { return _pendingKeys.pop(); } void clearEvents(); + void clearKeyboard(); void wait(int numFrames); diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index e103213eb5..a05ec6f359 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -120,4 +120,8 @@ void Inventory::putInv(int slamit) { // TODO } +void Inventory::invent(int flag) { + // TODO +} + } // End of namespace Sherlock diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index 01a325e382..6d61378b99 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -63,6 +63,8 @@ public: int findInv(const Common::String &name); void putInv(int slamit); + + void invent(int flag); }; } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 8e5cbb68ef..2827e80b78 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -528,12 +528,188 @@ void UserInterface::doInvControl() { // TODO } +/** + * Handles waiting whilst an object's description window is open. + */ void UserInterface::doLookControl() { - // TODO + Events &events = *_vm->_events; + Inventory &inv = *_vm->_inventory; + Screen &screen = *_vm->_screen; + + _key = _oldKey = -1; + _keyboardInput = _keycode != Common::KEYCODE_INVALID; + + if (events._released || events._rightReleased || _keyboardInput) { + // Is an inventory object being looked at? + if (!_invLookFlag) { + // Is there any remaining text to display? + if (!_descStr.empty()) { + printObjectDesc(_descStr, false); + } else if (!_lookHelp) { + // Need to close the window and depress the Look button + Common::Point pt(MENU_POINTS[0][0], MENU_POINTS[0][1]); + Surface tempSurface((*_controls)[0]._frame.w, (*_controls)[0]._frame.h); + tempSurface.blitFrom(screen._backBuffer2, Common::Point(0, 0), + Common::Rect(pt.x, pt.y, pt.x + (*_controls)[0]._frame.w, + pt.y + (*_controls)[1]._frame.h)); + + screen._backBuffer2.blitFrom((*_controls)[0]._frame, pt); + banishWindow(true); + + _windowBounds.top = CONTROLS_Y1; + _key = _oldKey = COMMANDS[LOOK_MODE - 1]; + _temp = _oldTemp = 0; + _menuMode = LOOK_MODE; + events.clearEvents(); + + screen._backBuffer2.blitFrom(tempSurface, pt); + } + } else { + // Looking at an inventory object + // Backup the user interface + Surface tempSurface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y1); + tempSurface.blitFrom(screen._backBuffer2, Common::Point(0, 0), + Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + + inv.invent(128); + banishWindow(true); + + // Restore the ui + screen._backBuffer2.blitFrom(tempSurface, Common::Point(0, CONTROLS_Y1)); + } + + _windowBounds.top = CONTROLS_Y1; + _key = _oldKey = COMMANDS[LOOK_MODE - 1]; + _temp = _oldTemp = 0; + events.clearEvents(); + _invLookFlag = false; + _menuMode = INV_MODE; + _windowOpen = true; + } } +/** + * Handles input until one of the user interface buttons/commands is selected + */ void UserInterface::doMainControl() { - // TODO + Events &events = *_vm->_events; + Inventory &inv = *_vm->_inventory; + Common::Point pt = events.mousePos(); + + if ((events._pressed || events._released) && pt.y > CONTROLS_Y) { + events.clearKeyboard(); + _key = -1; + + // Check whether the mouse is in any of the command areas + for (_temp = 0; (_temp < 12) && (_key == -1); ++_temp) { + Common::Rect r(MENU_POINTS[_temp][0], MENU_POINTS[_temp][1], + MENU_POINTS[_temp][2], MENU_POINTS[_temp][3]); + if (r.contains(pt)) + _key = COMMANDS[_temp]; + } + --_temp; + } else if (_keycode != Common::KEYCODE_INVALID) { + // Keyboard control + _keyboardInput = true; + + if (_keycode >= Common::KEYCODE_a && _keycode <= Common::KEYCODE_z) { + const char *c = strchr(COMMANDS, _keycode); + _temp = !c ? 12 : c - COMMANDS; + } else { + _temp = 12; + } + + if (_temp == 12) + _key = -1; + + if (events._rightPressed) { + _temp = 12; + _key = -1; + } + } else if (!events._released) { + _key = -1; + } + + // Check if the button being pointed to has changed + if (_oldKey != _key && !_windowOpen) { + // Clear the info line + _infoFlag++; + clearInfo(); + + // If there was an old button selected, restore it + if (_oldKey != -1) { + _menuMode = STD_MODE; + restoreButton(_oldTemp); + } + + // If a new button is being pointed to, highlight it + if (_key != -1 && _temp < 12 && !_keyboardInput) + depressButton(_temp); + + // Save the new button selection + _oldKey = _key; + _oldTemp = _temp; + } + + if (!events._pressed && !_windowOpen) { + switch (_key) { + case 'L': + toggleButton(0); + break; + case 'M': + toggleButton(1); + break; + case 'T': + toggleButton(2); + break; + case 'P': + toggleButton(3); + break; + case 'O': + toggleButton(4); + break; + case 'C': + toggleButton(5); + break; + case 'I': + pushButton(6); + _selector = _oldSelector = -1; + _menuMode = INV_MODE; + inv.invent(1); + break; + case 'U': + pushButton(7); + _selector = _oldSelector = -1; + _menuMode = USE_MODE; + inv.invent(2); + break; + case 'G': + pushButton(8); + _selector = _oldSelector = -1; + _menuMode = GIVE_MODE; + inv.invent(3); + break; + case 'J': + pushButton(9); + _menuMode = JOURNAL_MODE; + journalControl(); + break; + case 'F': + pushButton(10); + _menuMode = FILES_MODE; + environment(); + break; + case 'S': + pushButton(11); + _menuMode = SETUP_MODE; + doControls(); + break; + default: + break; + } + + _help = _oldHelp = _oldBgFound = -1; + } } void UserInterface::doMiscControl(int allowed) { @@ -548,6 +724,17 @@ void UserInterface::doTalkControl() { // TODO } +void UserInterface::journalControl() { + // TODO +} + +void UserInterface::environment() { + // TODO +} + +void UserInterface::doControls() { + // TODO +} /** * Print the description of an object diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index 291aa1e9d2..582d6f87ce 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -94,6 +94,10 @@ private: void doMiscControl(int allowed); void doPickControl(); void doTalkControl(); + void journalControl(); + + void environment(); + void doControls(); void makeButton(const Common::Rect &bounds, int textX, const Common::String &str); public: -- cgit v1.2.3 From 56a854e2292f420a6ab03c65174f9fc0310bc2fa Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 27 Mar 2015 19:52:46 -0400 Subject: SHERLOCK: Fixes for examine dialog display --- engines/sherlock/events.cpp | 2 +- engines/sherlock/scene.cpp | 15 ++++++---- engines/sherlock/scene.h | 1 - engines/sherlock/screen.h | 18 +++++++----- engines/sherlock/user_interface.cpp | 57 ++++++++++++++++++++++++++----------- engines/sherlock/user_interface.h | 5 +++- 6 files changed, 66 insertions(+), 32 deletions(-) diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index 5c94b7e1ff..fef22c9301 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -186,7 +186,7 @@ bool Events::checkForNextFrameCounter() { */ void Events::clearEvents() { _pendingKeys.clear(); - _pressed = _rightPressed = false; + _pressed = _released = false; _rightPressed = _rightReleased = false; _oldButtons = _oldRightButton = false; } diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 6442538794..97f7350ea9 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -106,12 +106,9 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { _animating = 0; _doBgAnimDone = true; _tempFadeStyle = 0; - - _controlPanel = new ImageFile("controls.vgs"); } Scene::~Scene() { - delete _controlPanel; freeScene(); } @@ -198,6 +195,7 @@ bool Scene::loadScene(const Common::String &filename) { People &people = *_vm->_people; Screen &screen = *_vm->_screen; Sound &sound = *_vm->_sound; + UserInterface &ui = *_vm->_ui; bool flag; freeScene(); @@ -393,9 +391,7 @@ bool Scene::loadScene(const Common::String &filename) { } // Clear user interface area and draw controls - screen._backBuffer2.fillRect(0, INFO_LINE, SHERLOCK_SCREEN_WIDTH, INFO_LINE + 10, INFO_BLACK); - screen._backBuffer.transBlitFrom((*_controlPanel)[0], Common::Point(0, CONTROLS_Y)); - screen._backBuffer2.transBlitFrom((*_controlPanel)[0], Common::Point(0, CONTROLS_Y)); + ui.drawInterface(); _changes = false; checkSceneStatus(); @@ -1074,6 +1070,13 @@ void Scene::doBgAnim() { events.setCursor((CursorId)cursorId); } + if (ui._menuMode == LOOK_MODE) { + if (mousePos.y > CONTROLS_Y1) + events.setCursor(ARROW); + else if (mousePos.y < CONTROLS_Y) + events.setCursor(MAGNIFY); + } + // Check for setting magnifying glass cursor if (ui._menuMode == INV_MODE || ui._menuMode == USE_MODE || ui._menuMode == GIVE_MODE) { if (_invMode == INVMODE_1) { diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 27313e34af..007f910b10 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -123,7 +123,6 @@ public: Common::Point _bigPos; Common::Point _overPos; int _charPoint, _oldCharPoint; - ImageFile *_controlPanel; int _keyboardInput; int _oldKey, _help, _oldHelp; int _oldTemp, _temp; diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 45a50e7e85..e8f45f7bba 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -36,13 +36,17 @@ namespace Sherlock { #define VGA_COLOR_TRANS(x) ((x) * 255 / 63) enum { - INFO_BLACK = 1, - INFO_FOREGROUND = 11, - INFO_BACKGROUND = 1, - BORDER_COLOR = 237, - INV_FOREGROUND = 14, - INV_BACKGROUND = 1, - COM_FOREGROUND = 15 + INFO_BLACK = 1, + INFO_FOREGROUND = 11, + INFO_BACKGROUND = 1, + BORDER_COLOR = 237, + INV_FOREGROUND = 14, + INV_BACKGROUND = 1, + COMMAND_HIGHLIGHTED = 10, + COMMAND_FOREGROUND = 15, + BUTTON_TOP = 233, + BUTTON_MIDDLE = 244, + BUTTON_BOTTOM = 248 }; class SherlockEngine; diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 2827e80b78..c15685d82b 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -60,6 +60,8 @@ const char *const PRESS_KEY_TO_CONTINUE = "Press any Key to Continue."; /*----------------------------------------------------------------*/ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { + _controls = new ImageFile("menu.all"); + _controlPanel = new ImageFile("controls.vgs"); _bgFound = 0; _oldBgFound = -1; _keycode = Common::KEYCODE_INVALID; @@ -81,12 +83,11 @@ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { _windowBounds = Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH - 1, SHERLOCK_SCREEN_HEIGHT - 1); _windowStyle = 0; - - _controls = new ImageFile("menu.all"); } UserInterface::~UserInterface() { delete _controls; + delete _controlPanel; } void UserInterface::reset() { @@ -95,6 +96,17 @@ void UserInterface::reset() { _oldTemp = _temp = -1; } +/** + * Draw the user interface onto the screen's back buffers + */ +void UserInterface::drawInterface() { + Screen &screen = *_vm->_screen; + + screen._backBuffer2.fillRect(0, INFO_LINE, SHERLOCK_SCREEN_WIDTH, INFO_LINE + 10, INFO_BLACK); + screen._backBuffer.transBlitFrom((*_controlPanel)[0], Common::Point(0, CONTROLS_Y)); + screen._backBuffer2.transBlitFrom((*_controlPanel)[0], Common::Point(0, CONTROLS_Y)); +} + /** * Main input handler for the user interface */ @@ -137,7 +149,7 @@ void UserInterface::handleInput() { (events._rightPressed || (!_helpStyle && !events._released)) && (_bgFound != -1) && (_bgFound < 1000) && (scene._bgShapes[_bgFound]._defaultCommand || - scene._bgShapes[_bgFound]._description[0])) { + !scene._bgShapes[_bgFound]._description.empty())) { // If there is no default command, so set it to Look if (scene._bgShapes[_bgFound]._defaultCommand) _help = scene._bgShapes[_bgFound]._defaultCommand - 1; @@ -151,7 +163,7 @@ void UserInterface::handleInput() { ((events._rightReleased && _helpStyle) || (events._released && !_helpStyle)) && (_bgFound != -1 && _bgFound < 1000) && (scene._bgShapes[_bgFound]._defaultCommand || - scene._bgShapes[_bgFound]._description[0])) { + !scene._bgShapes[_bgFound]._description.empty())) { // If there is no default command, set it to Look if (scene._bgShapes[_bgFound]._defaultCommand) _menuMode = (MenuMode)scene._bgShapes[_bgFound]._defaultCommand; @@ -491,7 +503,7 @@ void UserInterface::examine() { people.walkToCoords(obj._lookPosition, obj._lookFacing); } - if (talk._talkToAbort) { + if (!talk._talkToAbort) { _cAnimStr = obj._examine; if (obj._lookFlag) _vm->setFlags(obj._lookFlag); @@ -548,11 +560,6 @@ void UserInterface::doLookControl() { } else if (!_lookHelp) { // Need to close the window and depress the Look button Common::Point pt(MENU_POINTS[0][0], MENU_POINTS[0][1]); - Surface tempSurface((*_controls)[0]._frame.w, (*_controls)[0]._frame.h); - tempSurface.blitFrom(screen._backBuffer2, Common::Point(0, 0), - Common::Rect(pt.x, pt.y, pt.x + (*_controls)[0]._frame.w, - pt.y + (*_controls)[1]._frame.h)); - screen._backBuffer2.blitFrom((*_controls)[0]._frame, pt); banishWindow(true); @@ -562,7 +569,8 @@ void UserInterface::doLookControl() { _menuMode = LOOK_MODE; events.clearEvents(); - screen._backBuffer2.blitFrom(tempSurface, pt); + // Restore UI + drawInterface(); } } else { // Looking at an inventory object @@ -865,6 +873,10 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { Common::String line(lineStartP, msgP); screen.gPrint(Common::Point(16, CONTROLS_Y + 12 + lineNum * 9), INV_FOREGROUND, line.c_str()); + + if (!endOfStr) + // Start next line at start of the nxet word after space + ++msgP; } // Handle display depending on whether all the message was shown @@ -874,7 +886,7 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { PRESS_KEY_FOR_MORE); screen.gPrint(Common::Point((SHERLOCK_SCREEN_WIDTH - screen.stringWidth(PRESS_KEY_FOR_MORE)) / 2, CONTROLS_Y), - COM_FOREGROUND, "P"); + COMMAND_FOREGROUND, "P"); _descStr = msgP; } else { makeButton(Common::Rect(46, CONTROLS_Y, 272, CONTROLS_Y + 10), @@ -882,7 +894,7 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { PRESS_KEY_FOR_MORE); screen.gPrint(Common::Point((SHERLOCK_SCREEN_WIDTH - screen.stringWidth(PRESS_KEY_TO_CONTINUE)) / 2, CONTROLS_Y), - COM_FOREGROUND, "P"); + COMMAND_FOREGROUND, "P"); _descStr = ""; } @@ -913,15 +925,28 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { } /** -* Print the previously selected object's decription -*/ + * Print the previously selected object's decription + */ void UserInterface::printObjectDesc() { printObjectDesc(_cAnimStr, true); } +/** + * Draws a button for use in the inventory, talk, and examine dialogs. + */ void UserInterface::makeButton(const Common::Rect &bounds, int textX, const Common::String &str) { - // TODO + Screen &screen = *_vm->_screen; + + screen.bar(Common::Rect(bounds.left, bounds.top, bounds.right, bounds.top + 1), BUTTON_TOP); + screen.bar(Common::Rect(bounds.left, bounds.top, bounds.left + 1, bounds.bottom), BUTTON_TOP); + screen.bar(Common::Rect(bounds.right - 1, bounds.top, bounds.right, bounds.bottom), BUTTON_BOTTOM); + screen.bar(Common::Rect(bounds.left + 1, bounds.bottom - 1, bounds.right, bounds.bottom), BUTTON_BOTTOM); + screen.bar(Common::Rect(bounds.left + 1, bounds.top + 1, bounds.right - 1, bounds.bottom - 1), BUTTON_MIDDLE); + + screen.gPrint(Common::Point(textX, bounds.top), COMMAND_HIGHLIGHTED, "%c", str[0]); + screen.gPrint(Common::Point(textX + screen.charWidth(str[0]), bounds.top), + COMMAND_FOREGROUND, "%s", str.c_str() + 1); } /** diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index 582d6f87ce..f6e0435f48 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -51,6 +51,8 @@ class SherlockEngine; class UserInterface { private: SherlockEngine *_vm; + ImageFile *_controlPanel; + ImageFile *_controls; int _bgFound; int _oldBgFound; Common::KeyCode _keycode; @@ -60,7 +62,6 @@ private: int _key, _oldKey; int _temp, _oldTemp; int _invLookFlag; - ImageFile *_controls; int _oldLook; bool _keyboardInput; int _invMode; @@ -111,6 +112,8 @@ public: void reset(); + void drawInterface(); + void handleInput(); void clearInfo(); -- cgit v1.2.3 From e122b752b7faf6a0307e74523771860367f7227e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 27 Mar 2015 22:12:37 -0400 Subject: SHERLOCK: Fix scrolling examine window on-screen --- engines/sherlock/screen.cpp | 2 +- engines/sherlock/screen.h | 2 +- engines/sherlock/user_interface.cpp | 40 ++++++++++++++++++++----------------- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 646802094f..def20612b7 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -403,7 +403,7 @@ void Screen::writeString(const Common::String &str, const Common::Point &pt, int /** * Fills an area on the back buffer, and then copies it to the screen */ -void Screen::bar(const Common::Rect &r, int color) { +void Screen::vgaBar(const Common::Rect &r, int color) { _backBuffer.fillRect(r, color); slamRect(r); } diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index e8f45f7bba..acd122e0e9 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -109,7 +109,7 @@ public: int charWidth(char c); - void bar(const Common::Rect &r, int color); + void vgaBar(const Common::Rect &r, int color); }; } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index c15685d82b..6af698baa6 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -82,7 +82,7 @@ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { _selector = _oldSelector = -1; _windowBounds = Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH - 1, SHERLOCK_SCREEN_HEIGHT - 1); - _windowStyle = 0; + _windowStyle = 1; // Sliding windows } UserInterface::~UserInterface() { @@ -457,7 +457,7 @@ void UserInterface::toggleButton(int num) { */ void UserInterface::clearInfo() { if (_infoFlag) { - _vm->_screen->bar(Common::Rect(16, INFO_LINE, SHERLOCK_SCREEN_WIDTH - 19, + _vm->_screen->vgaBar(Common::Rect(16, INFO_LINE, SHERLOCK_SCREEN_WIDTH - 19, INFO_LINE + 10), INFO_BLACK); _infoFlag = false; _oldLook = -1; @@ -822,23 +822,24 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { return; } + Surface &bb = screen._backBuffer; if (firstTime) { // Only draw the border on the first call _infoFlag = true; clearInfo(); - screen.bar(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, + bb.fillRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y1 + 10), BORDER_COLOR); - screen.bar(Common::Rect(0, CONTROLS_Y + 10, 1, SHERLOCK_SCREEN_HEIGHT - 1), + bb.fillRect(Common::Rect(0, CONTROLS_Y + 10, 1, SHERLOCK_SCREEN_HEIGHT - 1), BORDER_COLOR); - screen.bar(Common::Rect(SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y + 10, + bb.fillRect(Common::Rect(SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y + 10, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); - screen.bar(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - 1, SHERLOCK_SCREEN_WIDTH, + bb.fillRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - 1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); } // Clear background - screen.bar(Common::Rect(2, CONTROLS_Y + 10, SHERLOCK_SCREEN_WIDTH - 2, + bb.fillRect(Common::Rect(2, CONTROLS_Y + 10, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT - 2), INV_BACKGROUND); _windowBounds.top = CONTROLS_Y; @@ -904,15 +905,17 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); } else { + // Extract the window that's been drawn on the back buffer Surface tempSurface(SHERLOCK_SCREEN_WIDTH, - (SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y) + 10); + (SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y)); Common::Rect r(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + tempSurface.blitFrom(screen._backBuffer, Common::Point(0, 0), r); - tempSurface.blitFrom(screen._backBuffer, Common::Point(0, CONTROLS_Y), r); + // Remove drawn window with original user interface screen._backBuffer.blitFrom(screen._backBuffer2, Common::Point(0, CONTROLS_Y), r); - // Display the window + // Display the window gradually on-screen summonWindow(tempSurface); } @@ -938,11 +941,12 @@ void UserInterface::makeButton(const Common::Rect &bounds, int textX, const Common::String &str) { Screen &screen = *_vm->_screen; - screen.bar(Common::Rect(bounds.left, bounds.top, bounds.right, bounds.top + 1), BUTTON_TOP); - screen.bar(Common::Rect(bounds.left, bounds.top, bounds.left + 1, bounds.bottom), BUTTON_TOP); - screen.bar(Common::Rect(bounds.right - 1, bounds.top, bounds.right, bounds.bottom), BUTTON_BOTTOM); - screen.bar(Common::Rect(bounds.left + 1, bounds.bottom - 1, bounds.right, bounds.bottom), BUTTON_BOTTOM); - screen.bar(Common::Rect(bounds.left + 1, bounds.top + 1, bounds.right - 1, bounds.bottom - 1), BUTTON_MIDDLE); + Surface &bb = screen._backBuffer; + bb.fillRect(Common::Rect(bounds.left, bounds.top, bounds.right, bounds.top + 1), BUTTON_TOP); + bb.fillRect(Common::Rect(bounds.left, bounds.top, bounds.left + 1, bounds.bottom), BUTTON_TOP); + bb.fillRect(Common::Rect(bounds.right - 1, bounds.top, bounds.right, bounds.bottom), BUTTON_BOTTOM); + bb.fillRect(Common::Rect(bounds.left + 1, bounds.bottom - 1, bounds.right, bounds.bottom), BUTTON_BOTTOM); + bb.fillRect(Common::Rect(bounds.left + 1, bounds.top + 1, bounds.right - 1, bounds.bottom - 1), BUTTON_MIDDLE); screen.gPrint(Common::Point(textX, bounds.top), COMMAND_HIGHLIGHTED, "%c", str[0]); screen.gPrint(Common::Point(textX + screen.charWidth(str[0]), bounds.top), @@ -950,7 +954,7 @@ void UserInterface::makeButton(const Common::Rect &bounds, int textX, } /** - * Displays a passed window by gradually displaying it up vertically + * Displays a passed window by gradually scrolling it vertically on-screen */ void UserInterface::summonWindow(const Surface &bgSurface) { Events &events = *_vm->_events; @@ -961,8 +965,8 @@ void UserInterface::summonWindow(const Surface &bgSurface) { return; // Gradually slide up the display of the window - for (int idx = 1; idx <= (SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y); idx += 2) { - screen.blitFrom(bgSurface, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - idx), + for (int idx = 1; idx <= bgSurface.h; idx += 2) { + screen._backBuffer.blitFrom(bgSurface, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - idx), Common::Rect(0, 0, bgSurface.w, idx)); screen.slamRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - idx, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); -- cgit v1.2.3 From 5b1ad857b7cd0b6065c01e000dfadb80526a1729 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 27 Mar 2015 23:04:49 -0400 Subject: SHERLOCK: Fix for sliding examine dialog off-screen --- engines/sherlock/user_interface.cpp | 45 ++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 6af698baa6..61d6c6a76e 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -571,6 +571,14 @@ void UserInterface::doLookControl() { // Restore UI drawInterface(); + } else { + events.setCursor(ARROW); + banishWindow(true); + _windowBounds.top = CONTROLS_Y1; + _key = _oldKey = -1; + _temp = _oldTemp = 0; + _menuMode = STD_MODE; + events.clearEvents(); } } else { // Looking at an inventory object @@ -984,24 +992,28 @@ void UserInterface::summonWindow(const Surface &bgSurface) { /** * Close a currently open window - * @param flag 0 = slide old window down, 1 = slide old window up + * @param flag 0 = slide old window down, 1 = slide prior UI back up */ void UserInterface::banishWindow(bool flag) { Events &events = *_vm->_events; Screen &screen = *_vm->_screen; if (_windowOpen) { - if (!flag || !_windowStyle) { - // Slide window up - // Only slide the window up if the window style allows it + if (flag || !_windowStyle) { + // Slide window down + // Only slide the window if the window style allows it if (_windowStyle) { for (int idx = 2; idx < (SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y); idx += 2) { - byte *pSrc = (byte *)screen._backBuffer.getBasePtr(0, CONTROLS_Y); - Common::copy(pSrc, pSrc + (SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y + idx) - * SHERLOCK_SCREEN_WIDTH, pSrc - SHERLOCK_SCREEN_WIDTH * 2); + // Shift the window down by 2 lines + byte *pSrc = (byte *)screen._backBuffer.getBasePtr(0, CONTROLS_Y + idx - 2); + byte *pSrcEnd = (byte *)screen._backBuffer.getBasePtr(0, SHERLOCK_SCREEN_HEIGHT - 2); + byte *pDest = (byte *)screen._backBuffer.getBasePtr(0, SHERLOCK_SCREEN_HEIGHT); + Common::copy_backward(pSrc, pSrcEnd, pDest); + + // Restore lines from the ui in the secondary back buffer screen._backBuffer.blitFrom(screen._backBuffer2, Common::Point(0, CONTROLS_Y), - Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_HEIGHT, CONTROLS_Y + idx)); + Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y + idx)); screen.slamArea(0, CONTROLS_Y + idx - 2, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y - idx + 2); @@ -1023,14 +1035,15 @@ void UserInterface::banishWindow(bool flag) { SHERLOCK_SCREEN_HEIGHT)); } } else { - for (int idx = SHERLOCK_SCREEN_HEIGHT - 1 - CONTROLS_Y1; idx >= 0; idx -= 2) { - byte *pSrc = (byte *)screen._backBuffer.getBasePtr(0, CONTROLS_Y1 + idx); - byte *pDest = (byte *)screen._backBuffer.getBasePtr(0, CONTROLS_Y1); - - Common::copy(pSrc, pSrc + (SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y1 - idx) - * SHERLOCK_SCREEN_WIDTH, pDest); - screen.slamArea(0, CONTROLS_Y1 + idx, SHERLOCK_SCREEN_WIDTH, - SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y1 - idx); + // Slide the original user interface up to cover the dialog + for (int idx = 1; idx < (SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y1); idx += 2) { + byte *pSrc = (byte *)screen._backBuffer2.getBasePtr(0, CONTROLS_Y1); + byte *pSrcEnd = (byte *)screen._backBuffer2.getBasePtr(0, CONTROLS_Y1 + idx); + byte *pDest = (byte *)screen._backBuffer.getBasePtr(0, SHERLOCK_SCREEN_HEIGHT - idx); + Common::copy(pSrc, pSrcEnd, pDest); + + screen.slamArea(0, SHERLOCK_SCREEN_HEIGHT - idx, SHERLOCK_SCREEN_WIDTH, + SHERLOCK_SCREEN_HEIGHT); events.delay(10); } } -- cgit v1.2.3 From c047009ee10d8de67ee17088aad4ca131d907a8a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 27 Mar 2015 23:10:36 -0400 Subject: SHERLOCK: Fix hotspots working again after examining an object --- engines/sherlock/user_interface.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 61d6c6a76e..54c1f8e0fc 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -580,7 +580,8 @@ void UserInterface::doLookControl() { _menuMode = STD_MODE; events.clearEvents(); } - } else { + } + else { // Looking at an inventory object // Backup the user interface Surface tempSurface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y1); @@ -592,15 +593,15 @@ void UserInterface::doLookControl() { // Restore the ui screen._backBuffer2.blitFrom(tempSurface, Common::Point(0, CONTROLS_Y1)); - } - _windowBounds.top = CONTROLS_Y1; - _key = _oldKey = COMMANDS[LOOK_MODE - 1]; - _temp = _oldTemp = 0; - events.clearEvents(); - _invLookFlag = false; - _menuMode = INV_MODE; - _windowOpen = true; + _windowBounds.top = CONTROLS_Y1; + _key = _oldKey = COMMANDS[LOOK_MODE - 1]; + _temp = _oldTemp = 0; + events.clearEvents(); + _invLookFlag = false; + _menuMode = INV_MODE; + _windowOpen = true; + } } } @@ -900,7 +901,7 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { } else { makeButton(Common::Rect(46, CONTROLS_Y, 272, CONTROLS_Y + 10), (SHERLOCK_SCREEN_WIDTH - screen.stringWidth(PRESS_KEY_TO_CONTINUE)) / 2, - PRESS_KEY_FOR_MORE); + PRESS_KEY_TO_CONTINUE); screen.gPrint(Common::Point((SHERLOCK_SCREEN_WIDTH - screen.stringWidth(PRESS_KEY_TO_CONTINUE)) / 2, CONTROLS_Y), COMMAND_FOREGROUND, "P"); -- cgit v1.2.3 From 91df82c3e1599a658a7e4897bebf747e0e7fc189 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 27 Mar 2015 23:24:54 -0400 Subject: SHERLOCK: Fix mouse cursor hotspots --- engines/sherlock/events.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index fef22c9301..d147fe1f4c 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -67,7 +67,7 @@ void Events::setCursor(CursorId cursorId) { // Set the cursor data Graphics::Surface &s = (*_cursorImages)[cursorId]; - CursorMan.replaceCursor(s.getPixels(), s.w, s.h, s.w / 2, s.h / 2, 0xff); + CursorMan.replaceCursor(s.getPixels(), s.w, s.h, 0, 0, 0xff); showCursor(); } -- cgit v1.2.3 From ebda40038b72fd34673e2a6e8a29b4ec47d1ee54 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 28 Mar 2015 10:32:00 -0400 Subject: SHERLOCK: Add partial on-screen clipping to blitFrom --- engines/sherlock/graphics.cpp | 71 +++++++++++++++++++++++++------------ engines/sherlock/graphics.h | 2 ++ engines/sherlock/user_interface.cpp | 2 +- 3 files changed, 51 insertions(+), 24 deletions(-) diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index 1a0144bc4b..306ff23548 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -85,9 +85,15 @@ void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt) { */ void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds) { - addDirtyRect(Common::Rect(pt.x, pt.y, pt.x + srcBounds.width(), - pt.y + srcBounds.height())); - copyRectToSurface(src, pt.x, pt.y, srcBounds); + Common::Rect destRect(pt.x, pt.y, pt.x + srcBounds.width(), + pt.y + srcBounds.height()); + Common::Rect srcRect = srcBounds; + + if (clip(srcRect, destRect)) { + // Surface is at least partially or completely on-screen + addDirtyRect(destRect); + copyRectToSurface(src, destRect.left, destRect.top, srcRect); + } } /** @@ -104,32 +110,18 @@ void Surface::transBlitFrom(const ImageFrame &src, const Common::Point &pt, void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &pt, bool flipped, int overrideColor) { Common::Rect drawRect(0, 0, src.w, src.h); - Common::Point destPt = pt; - - if (destPt.x < 0) { - drawRect.left += -destPt.x; - destPt.x = 0; - } - if (destPt.y < 0) { - drawRect.top += -destPt.y; - destPt.y = 0; - } - int right = destPt.x + src.w; - if (right > this->w) { - drawRect.right -= (right - this->w); - } - int bottom = destPt.y + src.h; - if (bottom > this->h) { - drawRect.bottom -= (bottom - this->h); - } - - if (!drawRect.isValidRect()) + Common::Rect destRect(pt.x, pt.y, pt.x + src.w, pt.y + src.h); + + // Clip the display area to on-screen + if (!clip(drawRect, destRect)) + // It's completely off-screen return; if (flipped) drawRect = Common::Rect(src.w - drawRect.right, src.h - drawRect.bottom, src.w - drawRect.left, src.h - drawRect.top); + Common::Point destPt(destRect.left, destRect.top); addDirtyRect(Common::Rect(destPt.x, destPt.y, destPt.x + drawRect.width(), destPt.y + drawRect.height())); @@ -169,4 +161,37 @@ Surface Surface::getSubArea(const Common::Rect &r) { return Surface(*this, r); } +/** + * Clips the given source bounds so the passed destBounds will be entirely on-screen + */ +bool Surface::clip(Common::Rect &srcBounds, Common::Rect &destBounds) { + if (destBounds.left >= this->w || destBounds.top >= this->h || + destBounds.right <= 0 || destBounds.bottom <= 0) + return false; + + // Clip the bounds if necessary to fit on-screen + if (destBounds.right > this->w) { + srcBounds.right -= destBounds.right - this->w; + destBounds.right = this->w; + } + + if (destBounds.bottom > this->h) { + srcBounds.bottom -= destBounds.bottom - this->h; + destBounds.bottom = this->h; + } + + if (destBounds.top < 0) { + srcBounds.top += -destBounds.top; + destBounds.top = 0; + } + + if (destBounds.left < 0) { + srcBounds.left += -destBounds.left; + destBounds.left = 0; + } + + return true; +} + + } // End of namespace Sherlock diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index c380d805b2..b54dc1ec37 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -32,6 +32,8 @@ namespace Sherlock { class Surface : public Graphics::Surface { private: bool _freePixels; + + bool clip(Common::Rect &srcBounds, Common::Rect &destBounds); protected: virtual void addDirtyRect(const Common::Rect &r) {} diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 54c1f8e0fc..61933cf9f3 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -257,7 +257,7 @@ void UserInterface::handleInput() { if (!events._released) lookScreen(pt); } else { - personFound = scene._bgShapes[_bgFound]._aType == PERSON && _bgFound != -1; + personFound = _bgFound != -1 && scene._bgShapes[_bgFound]._aType == PERSON; } if (events._released && personFound) -- cgit v1.2.3 From 35df6bb7ed44f78548ff7ab6b63fccc4e5b1609f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 28 Mar 2015 16:28:48 -0400 Subject: SHERLOCK: Implemented doInvControl --- engines/sherlock/inventory.cpp | 12 ++ engines/sherlock/inventory.h | 6 + engines/sherlock/user_interface.cpp | 241 +++++++++++++++++++++++++++++++++++- engines/sherlock/user_interface.h | 9 ++ 4 files changed, 267 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index a05ec6f359..75ee364123 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -124,4 +124,16 @@ void Inventory::invent(int flag) { // TODO } +void Inventory::invCommands(bool slamIt) { + // TODO +} + +void Inventory::doInvLite(int index, byte color) { + // TODO +} + +void Inventory::doInvJF() { + // TODO +} + } // End of namespace Sherlock diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index 6d61378b99..0fa8eb0824 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -65,6 +65,12 @@ public: void putInv(int slamit); void invent(int flag); + + void invCommands(bool slamIt); + + void doInvLite(int index, byte color); + + void doInvJF(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 61933cf9f3..10b13cedbe 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -77,12 +77,14 @@ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { _oldLook = false; _keyboardInput = false; _invMode = 0; + _invIndex = 0; _pause = false; _cNum = 0; _selector = _oldSelector = -1; _windowBounds = Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH - 1, SHERLOCK_SCREEN_HEIGHT - 1); _windowStyle = 1; // Sliding windows + _find = 0; } UserInterface::~UserInterface() { @@ -451,6 +453,10 @@ void UserInterface::toggleButton(int num) { } } +void UserInterface::buttonPrint(const Common::Point &pt, int color, bool slamIt, + const Common::String &str) { + // TODO +} /** * Clears the info line of the screen @@ -536,8 +542,235 @@ void UserInterface::doEnvControl() { // TODO } +/** + * Handle input whilst the inventory is active + */ void UserInterface::doInvControl() { - // TODO + Events &events = *_vm->_events; + Inventory &inv = *_vm->_inventory; + Scene &scene = *_vm->_scene; + Screen &screen = *_vm->_screen; + Talk &talk = *_vm->_talk; + const char INVENTORY_COMMANDS[9] = { "ELUG-+,." }; + int colors[8]; + Common::Point mousePos = events.mousePos(); + + _key = _oldKey = -1; + _keyboardInput = false; + + // Check whether any inventory slot is highlighted + int found = -1; + Common::fill(&colors[0], &colors[8], (int)COMMAND_FOREGROUND); + for (int idx = 0; idx < 8; ++idx) { + Common::Rect r(INVENTORY_POINTS[idx][0], CONTROLS_Y1, + INVENTORY_POINTS[idx][1], CONTROLS_Y1 + 10); + if (r.contains(mousePos)) { + found = idx; + break; + } + } + + if (events._pressed || events._released) { + events.clearKeyboard(); + + if (found != -1) + // If a slot highlighted, set it's color + colors[found] = COMMAND_HIGHLIGHTED; + buttonPrint(Common::Point(INVENTORY_POINTS[0][2], CONTROLS_Y1), + colors[0], true, "Exit"); + + if (found >= 0 && found <= 3) { + buttonPrint(Common::Point(INVENTORY_POINTS[1][2], CONTROLS_Y1), colors[1], true, "Look"); + buttonPrint(Common::Point(INVENTORY_POINTS[2][2], CONTROLS_Y1), colors[1], true, "Use"); + buttonPrint(Common::Point(INVENTORY_POINTS[3][2], CONTROLS_Y1), colors[1], true, "Give"); + _invMode = found; + _selector = -1; + } + + if (_invIndex) { + screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1), + colors[4], "^^"); + screen.print(Common::Point(INVENTORY_POINTS[5][2], CONTROLS_Y1 + 1), + colors[5], "^"); + } + + if ((inv._holdings - _invIndex) > 6) { + screen.print(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1 + 1), + colors[6], "^^"); + screen.print(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1 + 1), + colors[7], "^"); + } + + bool flag = false; + if (_invMode == 1 || _invMode == 2 || _invMode == 3) { + Common::Rect r(15, CONTROLS_Y1 + 11, 314, SHERLOCK_SCREEN_HEIGHT - 2); + flag = (_selector < inv._holdings); + } + + if (!flag && mousePos.y >(CONTROLS_Y1 + 11)) + _selector = -1; + } + + if (_keycode != Common::KEYCODE_INVALID) { + _key = toupper(_keycode); + + if (_key == Common::KEYCODE_ESCAPE) + // Escape will also 'E'xit out of inventory display + _key = Common::KEYCODE_e; + + if (_key == 'E' || _key == 'L' || _key == 'U' || _key == 'G' + || _key == '-' || _key == '+') { + int temp = _invMode; + + const char *chP = strchr(INVENTORY_COMMANDS, _key); + _invMode = !chP ? 8 : chP - INVENTORY_COMMANDS; + inv.invCommands(true); + + _invMode = temp; + _keyboardInput = true; + if (_key == 'E') + _invMode = STD_MODE; + _selector = -1; + } else { + _selector = -1; + } + } + + if (_selector != _oldSelector) { + if (_oldSelector != -1) { + // Un-highlight + if (_oldSelector >= _invIndex && _oldSelector < (_invIndex + 6)) + inv.doInvLite(_oldSelector, BUTTON_MIDDLE); + } + + if (_selector != -1) + inv.doInvLite(_selector, 235); + + _oldSelector = _selector; + } + + if (events._released || _keyboardInput) { + if ((!found && events._released) && _key == 'E') { + inv.freeInv(); + _infoFlag = true; + clearInfo(); + banishWindow(false); + _key = -1; + events.clearEvents(); + events.setCursor(ARROW); + } else if ((found == 1 && events._released) || (_key == 'L')) { + _invMode = 1; + } else if ((found == 2 && events._released) || (_key == 'U')) { + _invMode = 2; + } else if ((found == 3 && events._released) || (_key == 'G')) { + _invMode = 3; + } else if (((found == 4 && events._released) || _key == ',') && _invIndex) { + if (_invIndex >= 6) + _invIndex -= 6; + else + _invIndex = 0; + + screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1), + COMMAND_HIGHLIGHTED, "^^"); + inv.freeGraphics(); + inv.loadGraphics(); + inv.putInv(1); + inv.invCommands(true); + } else if (((found == 5 && events._released) || _key == '-') && _invIndex) { + --_invIndex; + screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1), + COMMAND_HIGHLIGHTED, "^"); + inv.freeGraphics(); + inv.loadGraphics(); + inv.putInv(1); + inv.invCommands(true); + } else if (((found == 6 && events._released) || _key == '+') && (inv._holdings - _invIndex) > 6) { + ++_invIndex; + screen.print(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1 + 1), + COMMAND_HIGHLIGHTED, "_"); + inv.freeGraphics(); + inv.loadGraphics(); + inv.putInv(1); + inv.invCommands(true); + } else if (((found == 7 && events._released) || _key == '.') && (inv._holdings - _invIndex) > 6) { + _invIndex += 6; + if ((inv._holdings - 6) < _invIndex) + _invIndex = inv._holdings - 6; + + screen.print(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1 + 1), + COMMAND_HIGHLIGHTED, "_"); + inv.freeGraphics(); + inv.loadGraphics(); + inv.putInv(1); + inv.invCommands(true); + } else { + // If something is being given, make sure it's to a person + if (_invMode == 3) { + if (_bgFound != -1 && scene._bgShapes[_bgFound]._aType == PERSON) + _find = _bgFound; + else + _find = -1; + } else { + _find = _bgFound; + } + + if ((mousePos.y < CONTROLS_Y1) && (_invMode == 1) && (_find >= 0) && (_find < 1000)) { + if (!scene._bgShapes[_find]._examine.empty() && + scene._bgShapes[_find]._examine[0] >= ' ') + inv.doInvJF(); + } else if (_selector != -1 || _find >= 0) { + // Selector is the inventory object that was clicked on, or selected. + // If it's -1, then no inventory item is highlighted yet. Otherwise, + // an object in the scene has been clicked. + + if (_selector != -1 && _invMode == 1 && mousePos.y >(CONTROLS_Y1 + 11)) + inv.doInvJF(); + + if (talk._talkToAbort) + return; + + // Now check for the Use and Give actions. If inv_mode is 3, + // that means GIVE is in effect, _selector is the object being + // given, and _find is the target. + // The same applies to USE, except if _selector is -1, then USE + // is being tried on an object in the scene without an inventory + // object being highlighted first. + + if ((_invMode == 2 || (_selector != -1 && _invMode == 3)) && _find >= 0) { + events._pressed = events._released = false; + _infoFlag = true; + clearInfo(); + + int temp = _selector; // Save the selector + _selector = -1; + + inv.putInv(1); + _selector = temp; // Restore it + temp = _invMode; + _invMode = -1; + inv.invCommands(true); + + _infoFlag = true; + clearInfo(); + banishWindow(false); + _key = -1; + + inv.freeInv(); + + if (_selector >= 0) + // Use/Give inv object with scene object + checkUseAction(scene._bgShapes[_find]._use[0], inv[_selector]._name, + _muse, _find, temp - 2); + else + // Now inv object has been highlighted + checkUseAction(scene._bgShapes[_find]._use[0], "*SELF", _muse, + _find, temp - 2); + + _selector = _oldSelector = -1; + } + } + } + } } /** @@ -1056,4 +1289,10 @@ void UserInterface::banishWindow(bool flag) { _menuMode = STD_MODE; } +void UserInterface::checkUseAction(UseType &use, const Common::String &invName, + const Common::String &msg, int objNum, int giveMode) { + // TODO +} + + } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index f6e0435f48..d94b2fadc5 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -26,6 +26,7 @@ #include "common/scummsys.h" #include "common/events.h" #include "sherlock/graphics.h" +#include "sherlock/objects.h" #include "sherlock/resources.h" namespace Sherlock { @@ -65,6 +66,7 @@ private: int _oldLook; bool _keyboardInput; int _invMode; + int _invIndex; bool _pause; int _cNum; int _selector, _oldSelector; @@ -73,6 +75,8 @@ private: Common::Rect _windowBounds; Common::String _descStr; int _windowStyle; + int _find; + Common::String _muse; private: void depressButton(int num); @@ -82,6 +86,8 @@ private: void toggleButton(int num); + void buttonPrint(const Common::Point &pt, int color, bool slamIt, const Common::String &str); + void examine(); void lookScreen(const Common::Point &pt); @@ -101,6 +107,9 @@ private: void doControls(); void makeButton(const Common::Rect &bounds, int textX, const Common::String &str); + + void checkUseAction(UseType &use, const Common::String &invName, const Common::String &msg, + int objNum, int giveMode); public: MenuMode _menuMode; int _menuCounter; -- cgit v1.2.3 From 073b7e075ccac02ecab922e03781b3663c92af6c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 28 Mar 2015 17:36:46 -0400 Subject: SHERLOCK: Implemented lookScreen --- engines/sherlock/screen.h | 3 +- engines/sherlock/user_interface.cpp | 139 +++++++++++++++++++++++++++++++++++- 2 files changed, 139 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index acd122e0e9..3ac40263c0 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -46,7 +46,8 @@ enum { COMMAND_FOREGROUND = 15, BUTTON_TOP = 233, BUTTON_MIDDLE = 244, - BUTTON_BOTTOM = 248 + BUTTON_BOTTOM = 248, + TALK_FOREGROUND = 12 }; class SherlockEngine; diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 10b13cedbe..9710c3a74a 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -530,12 +530,147 @@ void UserInterface::examine() { } } +/** + * Print the name of an object in the scene + */ void UserInterface::lookScreen(const Common::Point &pt) { - // TODO + Events &events = *_vm->_events; + Inventory &inv = *_vm->_inventory; + Scene &scene = *_vm->_scene; + Screen &screen = *_vm->_screen; + Common::Point mousePos = events.mousePos(); + int temp; + Common::String tempStr; + int x, width, width1, width2 = 0; + + // Don't display anything for right button command + if ((events._rightPressed || events._rightPressed) && !events._pressed) + return; + + if (mousePos.y < CONTROLS_Y && (temp = _bgFound) != -1) { + if (temp != _oldLook) { + _infoFlag = true; + clearInfo(); + + if (temp < 1000) + tempStr = scene._bgShapes[temp]._description; + else + tempStr = scene._bgShapes[temp - 1000]._description; + + _infoFlag = true; + clearInfo(); + + // Only print description if there is one + if (!tempStr.empty() && tempStr[0] != ' ') { + // If inventory is active and an item is selected for a Use or Give action + if ((_menuMode == INV_MODE || _menuMode == USE_MODE || _menuMode == GIVE_MODE) && + (_invMode == 2 || _invMode == 3)) { + width1 = screen.stringWidth(inv[_selector]._name); + + if (_invMode == 2) { + // Using an object + x = width = screen.stringWidth("Use "); + + if (temp < 1000 && scene._bgShapes[temp]._aType != PERSON) + // It's not a person, so make it lowercase + tempStr.setChar(tolower(tempStr[0]), 0); + + x += screen.stringWidth(tempStr); + + // If we're using an inventory object, add in the width + // of the object name and the " on " + if (_selector != -1) { + x += width1; + width2 = screen.stringWidth(" on "); + x += width2; + } + + // If the line will be too long, keep cutting off characters + // until the string will fit + while (x > 280) { + x -= screen.charWidth(tempStr.lastChar()); + tempStr.deleteLastChar(); + } + + int xStart = (SHERLOCK_SCREEN_HEIGHT - x) / 2; + screen.print(Common::Point(xStart, INFO_LINE + 1), + INFO_FOREGROUND, "Use "); + + if (_selector != -1) { + screen.print(Common::Point(xStart + width, INFO_LINE + 1), + TALK_FOREGROUND, inv[_selector]._name.c_str()); + screen.print(Common::Point(xStart + width + width1, INFO_LINE + 1), + INFO_FOREGROUND, " on "); + screen.print(Common::Point(xStart + width + width1 + width2, INFO_LINE + 1), + INFO_FOREGROUND, tempStr.c_str()); + } else { + screen.print(Common::Point(xStart + width, INFO_LINE + 1), + INFO_FOREGROUND, tempStr.c_str()); + } + } else if (temp >= 0 && temp < 1000 && _selector != -1 && + scene._bgShapes[temp]._aType == PERSON) { + // Giving an object to a person + x = width = screen.stringWidth("Give "); + x += width1; + width2 = screen.stringWidth(" to "); + x += width2; + x += screen.stringWidth(tempStr); + + // Ensure string will fit on-screen + while (x > 280) { + x -= screen.charWidth(tempStr.lastChar()); + tempStr.deleteLastChar(); + } + + int xStart = (SHERLOCK_SCREEN_WIDTH - x) / 2; + screen.print(Common::Point(xStart, INFO_LINE + 1), + INFO_FOREGROUND, "Give "); + screen.print(Common::Point(xStart + width, INFO_LINE + 1), + TALK_FOREGROUND, inv[_selector]._name.c_str()); + screen.print(Common::Point(xStart + width + width1, INFO_LINE + 1), + INFO_FOREGROUND, " to "); + screen.print(Common::Point(xStart + width + width1 + width2, INFO_LINE + 1), + INFO_FOREGROUND, tempStr.c_str()); + } + } else { + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, tempStr.c_str()); + } + + _infoFlag = true; + _oldLook = temp; + } + } + } else { + clearInfo(); + } } +/** + * Gets the item in the inventory the mouse is on and display's it's description + */ void UserInterface::lookInv() { - // TODO + Events &events = *_vm->_events; + Inventory &inv = *_vm->_inventory; + Screen &screen = *_vm->_screen; + Common::Point mousePos = events.mousePos(); + + if (mousePos.x > 15 && mousePos.x < 314 && mousePos.y > (CONTROLS_Y1 + 11) + && mousePos.y < (SHERLOCK_SCREEN_HEIGHT - 2)) { + int temp = (mousePos.x - 6) / 52 + _invIndex; + if (temp < inv._holdings) { + if (temp < inv._holdings) { + clearInfo(); + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, + inv[temp]._description.c_str()); + _infoFlag = true; + _oldLook = temp; + } + } else { + clearInfo(); + } + } else { + clearInfo(); + } } void UserInterface::doEnvControl() { -- cgit v1.2.3 From c28416f38ef77eef0858756d0b3265c44ad90216 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 28 Mar 2015 20:13:57 -0400 Subject: SHERLOCK: Change the screen _backBuffer to be a pointer --- engines/sherlock/inventory.cpp | 19 +++++++++++++++++- engines/sherlock/inventory.h | 1 + engines/sherlock/objects.cpp | 2 +- engines/sherlock/scalpel/scalpel.cpp | 18 ++++++++--------- engines/sherlock/scene.cpp | 38 ++++++++++++++++++------------------ engines/sherlock/screen.cpp | 19 +++++++++--------- engines/sherlock/screen.h | 3 ++- engines/sherlock/user_interface.cpp | 34 ++++++++++++++++---------------- 8 files changed, 77 insertions(+), 57 deletions(-) diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index 75ee364123..8eb7ecc1a1 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -30,6 +30,7 @@ Inventory::Inventory(SherlockEngine *vm) : Common::Array(), _vm(v _invGraphicsLoaded = false; _invIndex = 0; _holdings = 0; + _oldFlag = 0; } Inventory::~Inventory() { @@ -120,8 +121,24 @@ void Inventory::putInv(int slamit) { // TODO } +/** + * Put the game into inventory mode and open the interface window. + * The flag parameter specifies the mode: + * 0 = plain inventory mode + * 2 = use inventory mode + * 3 = give inventory mode + * 128 = Draw window in the back buffer, but don't display it + */ void Inventory::invent(int flag) { - // TODO + Screen &screen = *_vm->_screen; + _oldFlag = 7; + loadInv(); + + if (flag == 128) { + screen._backBuffer = &screen._backBuffer2; + } + + } void Inventory::invCommands(bool slamIt) { diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index 0fa8eb0824..1db91292a5 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -50,6 +50,7 @@ public: int _invIndex; int _holdings; void freeGraphics(); + int _oldFlag; public: Inventory(SherlockEngine *vm); ~Inventory(); diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 39a9cf8014..d5d24e72af 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -656,7 +656,7 @@ bool Object::checkEndOfSequence() { if (seq == 99) { --_frameNumber; - screen._backBuffer.transBlitFrom(_imageFrame->_frame, _position); + screen._backBuffer1.transBlitFrom(_imageFrame->_frame, _position); screen._backBuffer2.transBlitFrom(_imageFrame->_frame, _position); _type = INVALID; } else { diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 3ec971895a..db59434f85 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -99,23 +99,23 @@ bool ScalpelEngine::showCityCutscene() { if (finished) { ImageFile titleImages("title2.vgs", true); - _screen->_backBuffer.blitFrom(*_screen); + _screen->_backBuffer1.blitFrom(*_screen); _screen->_backBuffer2.blitFrom(*_screen); // London, England - _screen->_backBuffer.transBlitFrom(titleImages[0], Common::Point(10, 11)); + _screen->_backBuffer1.transBlitFrom(titleImages[0], Common::Point(10, 11)); _screen->randomTransition(); finished = _events->delay(1000, true); // November, 1888 if (finished) { - _screen->_backBuffer.transBlitFrom(titleImages[1], Common::Point(101, 102)); + _screen->_backBuffer1.transBlitFrom(titleImages[1], Common::Point(101, 102)); _screen->randomTransition(); finished = _events->delay(5000, true); } // Transition out the title - _screen->_backBuffer.blitFrom(_screen->_backBuffer2); + _screen->_backBuffer1.blitFrom(_screen->_backBuffer2); _screen->randomTransition(); } @@ -124,21 +124,21 @@ bool ScalpelEngine::showCityCutscene() { if (finished) { ImageFile titleImages("title.vgs", true); - _screen->_backBuffer.blitFrom(*_screen); + _screen->_backBuffer1.blitFrom(*_screen); _screen->_backBuffer2.blitFrom(*_screen); // The Lost Files of - _screen->_backBuffer.transBlitFrom(titleImages[0], Common::Point(75, 6)); + _screen->_backBuffer1.transBlitFrom(titleImages[0], Common::Point(75, 6)); // Sherlock Holmes - _screen->_backBuffer.transBlitFrom(titleImages[1], Common::Point(34, 21)); + _screen->_backBuffer1.transBlitFrom(titleImages[1], Common::Point(34, 21)); // copyright - _screen->_backBuffer.transBlitFrom(titleImages[2], Common::Point(4, 190)); + _screen->_backBuffer1.transBlitFrom(titleImages[2], Common::Point(4, 190)); _screen->verticalTransition(); finished = _events->delay(4000, true); if (finished) { - _screen->_backBuffer.blitFrom(_screen->_backBuffer2); + _screen->_backBuffer1.blitFrom(_screen->_backBuffer2); _screen->randomTransition(); finished = _events->delay(2000); } diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 97f7350ea9..c3afc4a0d4 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -378,13 +378,13 @@ bool Scene::loadScene(const Common::String &filename) { Common::SeekableReadStream *bgStream = !_lzwMode ? rrmStream : decompressLZ(*rrmStream, SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT); - bgStream->read(screen._backBuffer.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT); + bgStream->read(screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT); if (_lzwMode) delete bgStream; - // Set the palette - screen._backBuffer2.blitFrom(screen._backBuffer); + // Backup the image and set the palette + screen._backBuffer2.blitFrom(screen._backBuffer1); screen.setPalette(screen._cMap); delete rrmStream; @@ -658,7 +658,7 @@ void Scene::transitionToScene() { if (screen._fadeStyle) screen.randomTransition(); else - screen.blitFrom(screen._backBuffer); + screen.blitFrom(screen._backBuffer1); if (cAnimNum != -1) { CAnim &c = _cAnim[cAnimNum]; @@ -696,7 +696,7 @@ int Scene::toggleObject(const Common::String &name) { void Scene::updateBackground() { People &people = *_vm->_people; Screen &screen = *_vm->_screen; - Surface surface = screen._backBuffer.getSubArea( + Surface surface = screen._backBuffer1.getSubArea( Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); Sprite &player = people[AL]; @@ -1055,7 +1055,7 @@ void Scene::doBgAnim() { Sound &sound = *_vm->_sound; Talk &talk = *_vm->_talk; UserInterface &ui = *_vm->_ui; - Surface surface = screen._backBuffer.getSubArea(Common::Rect(0, 0, + Surface surface = screen._backBuffer1.getSubArea(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); int cursorId = events.getCursor(); Common::Point mousePos = events.mousePos(); @@ -1126,7 +1126,7 @@ void Scene::doBgAnim() { if (people[AL]._type == CHARACTER) screen.restoreBackground(bounds); else if (people[AL]._type == REMOVE) - screen._backBuffer.blitFrom(screen._backBuffer2, pt, bounds); + screen._backBuffer1.blitFrom(screen._backBuffer2, pt, bounds); for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; @@ -1145,7 +1145,7 @@ void Scene::doBgAnim() { Object &o = _bgShapes[idx]; if (o._type == NO_SHAPE && ((o._flags & 1) == 0)) { // Restore screen area - screen._backBuffer.blitFrom(screen._backBuffer2, o._position, + screen._backBuffer1.blitFrom(screen._backBuffer2, o._position, Common::Rect(o._position.x, o._position.y, o._position.x + o._noShapeSize.x, o._position.y + o._noShapeSize.y)); @@ -1191,14 +1191,14 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == BEHIND) - screen._backBuffer.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + screen._backBuffer1.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); } // Draw all canimations which are behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == BEHIND) { - screen._backBuffer.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + screen._backBuffer1.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); } } @@ -1206,14 +1206,14 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == NORMAL_BEHIND) - screen._backBuffer.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + screen._backBuffer1.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); } // Draw all canimations which are NORMAL and behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == NORMAL_BEHIND) { - screen._backBuffer.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + screen._backBuffer1.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); } } @@ -1226,7 +1226,7 @@ void Scene::doBgAnim() { bool flipped = people[AL]._frameNumber == WALK_LEFT || people[AL]._frameNumber == STOP_LEFT || people[AL]._frameNumber == WALK_UPLEFT || people[AL]._frameNumber == STOP_UPLEFT || people[AL]._frameNumber == WALK_DOWNRIGHT || people[AL]._frameNumber == STOP_DOWNRIGHT; - screen._backBuffer.transBlitFrom(people[AL]._imageFrame->_frame, + screen._backBuffer1.transBlitFrom(people[AL]._imageFrame->_frame, Common::Point(tempX, people[AL]._position.y / 100 - people[AL]._imageFrame->_frame.h), flipped); } @@ -1234,14 +1234,14 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == NORMAL_FORWARD) - screen._backBuffer.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + screen._backBuffer1.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); } // Draw all static and active canimations that are NORMAL and are in front of the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == NORMAL_BEHIND) { - screen._backBuffer.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + screen._backBuffer1.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); } } @@ -1249,19 +1249,19 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == FORWARD) - screen._backBuffer.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + screen._backBuffer1.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); } // Draw any active portrait if (people._portraitLoaded && people._portrait._type == ACTIVE_BG_SHAPE) - screen._backBuffer.transBlitFrom(people._portrait._imageFrame->_frame, + screen._backBuffer1.transBlitFrom(people._portrait._imageFrame->_frame, people._portrait._position, people._portrait._flags & 2); // Draw all static and active canimations that are in front of the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == FORWARD) { - screen._backBuffer.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + screen._backBuffer1.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); } } @@ -1269,7 +1269,7 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if (o._type == NO_SHAPE && (o._flags & 1) == 0) - screen._backBuffer.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + screen._backBuffer1.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); } // Bring the newly built picture to the screen diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index def20612b7..f1562e2468 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -29,8 +29,9 @@ namespace Sherlock { Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), _vm(vm), - _backBuffer(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), - _backBuffer2(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT) { + _backBuffer1(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), + _backBuffer2(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), + _backBuffer(&_backBuffer1) { _transitionSeed = 1; _fadeStyle = false; _font = nullptr; @@ -201,7 +202,7 @@ void Screen::randomTransition() { int offset = _transitionSeed & 65535; if (offset < (SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCREEN_HEIGHT)) - *((byte *)getPixels() + offset) = *((const byte *)_backBuffer.getPixels() + offset); + *((byte *)getPixels() + offset) = *((const byte *)_backBuffer->getPixels() + offset); if (idx != 0 && (idx % 100) == 0) { // Ensure there's a full screen dirty rect for the next frame update @@ -214,7 +215,7 @@ void Screen::randomTransition() { } // Make sure everything has been transferred - blitFrom(_backBuffer); + blitFrom(_backBuffer1); } /** @@ -232,7 +233,7 @@ void Screen::verticalTransition() { _vm->getRandomNumber(3) + 1; if (temp) { - blitFrom(_backBuffer, Common::Point(xp, table[xp]), + blitFrom(_backBuffer1, Common::Point(xp, table[xp]), Common::Rect(xp, table[xp], xp + 1, table[xp] + temp)); table[xp] += temp; } @@ -251,7 +252,7 @@ void Screen::restoreBackground(const Common::Rect &r) { tempRect.clip(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); if (tempRect.isValidRect()) - _backBuffer.blitFrom(_backBuffer2, Common::Point(tempRect.left, tempRect.top), tempRect); + _backBuffer1.blitFrom(_backBuffer2, Common::Point(tempRect.left, tempRect.top), tempRect); } } @@ -271,7 +272,7 @@ void Screen::slamRect(const Common::Rect &r) { tempRect.clip(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); if (tempRect.isValidRect()) - blitFrom(_backBuffer, Common::Point(tempRect.left, tempRect.top), tempRect); + blitFrom(*_backBuffer, Common::Point(tempRect.left, tempRect.top), tempRect); } } @@ -394,7 +395,7 @@ void Screen::writeString(const Common::String &str, const Common::Point &pt, int else { assert(*c > ' ' && *c <= '~'); ImageFrame &frame = (*_font)[*c - 33]; - _backBuffer.transBlitFrom(frame, charPos, false, color); + _backBuffer->transBlitFrom(frame, charPos, false, color); charPos.x += frame._frame.w + 1; } } @@ -404,7 +405,7 @@ void Screen::writeString(const Common::String &str, const Common::Point &pt, int * Fills an area on the back buffer, and then copies it to the screen */ void Screen::vgaBar(const Common::Rect &r, int color) { - _backBuffer.fillRect(r, color); + _backBuffer->fillRect(r, color); slamRect(r); } diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 3ac40263c0..7d07cfa062 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -69,7 +69,8 @@ private: protected: virtual void addDirtyRect(const Common::Rect &r); public: - Surface _backBuffer, _backBuffer2; + Surface _backBuffer1, _backBuffer2; + Surface *_backBuffer; bool _fadeStyle; byte _cMap[PALETTE_SIZE]; byte _sMap[PALETTE_SIZE]; diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 9710c3a74a..dbc9108212 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -105,7 +105,7 @@ void UserInterface::drawInterface() { Screen &screen = *_vm->_screen; screen._backBuffer2.fillRect(0, INFO_LINE, SHERLOCK_SCREEN_WIDTH, INFO_LINE + 10, INFO_BLACK); - screen._backBuffer.transBlitFrom((*_controlPanel)[0], Common::Point(0, CONTROLS_Y)); + screen._backBuffer1.transBlitFrom((*_controlPanel)[0], Common::Point(0, CONTROLS_Y)); screen._backBuffer2.transBlitFrom((*_controlPanel)[0], Common::Point(0, CONTROLS_Y)); } @@ -376,7 +376,7 @@ void UserInterface::depressButton(int num) { Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]); Graphics::Surface &s = (*_controls)[num]._frame; - screen._backBuffer.transBlitFrom(s, pt); + screen._backBuffer1.transBlitFrom(s, pt); screen.slamArea(pt.x, pt.y, pt.x + s.w, pt.y + s.h); } @@ -389,7 +389,7 @@ void UserInterface::restoreButton(int num) { Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]); Graphics::Surface &frame = (*_controls)[num]._frame; - screen._backBuffer.blitFrom(screen._backBuffer2, pt, + screen._backBuffer1.blitFrom(screen._backBuffer2, pt, Common::Rect(pt.x, pt.y, pt.x + 90, pt.y + 19)); screen.slamArea(pt.x, pt.y, pt.x + frame.w, pt.y + frame.h); @@ -443,7 +443,7 @@ void UserInterface::toggleButton(int num) { Graphics::Surface &s = (*_controls)[num]._frame; Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]); - screen._backBuffer.transBlitFrom(s, pt); + screen._backBuffer1.transBlitFrom(s, pt); screen.slamArea(pt.x, pt.y, pt.x + s.w, pt.y + s.h); } } else { @@ -1199,7 +1199,7 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { return; } - Surface &bb = screen._backBuffer; + Surface &bb = *screen._backBuffer; if (firstTime) { // Only draw the border on the first call _infoFlag = true; @@ -1286,10 +1286,10 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { Surface tempSurface(SHERLOCK_SCREEN_WIDTH, (SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y)); Common::Rect r(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); - tempSurface.blitFrom(screen._backBuffer, Common::Point(0, 0), r); + tempSurface.blitFrom(screen._backBuffer1, Common::Point(0, 0), r); // Remove drawn window with original user interface - screen._backBuffer.blitFrom(screen._backBuffer2, + screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(0, CONTROLS_Y), r); // Display the window gradually on-screen @@ -1318,7 +1318,7 @@ void UserInterface::makeButton(const Common::Rect &bounds, int textX, const Common::String &str) { Screen &screen = *_vm->_screen; - Surface &bb = screen._backBuffer; + Surface &bb = *screen._backBuffer; bb.fillRect(Common::Rect(bounds.left, bounds.top, bounds.right, bounds.top + 1), BUTTON_TOP); bb.fillRect(Common::Rect(bounds.left, bounds.top, bounds.left + 1, bounds.bottom), BUTTON_TOP); bb.fillRect(Common::Rect(bounds.right - 1, bounds.top, bounds.right, bounds.bottom), BUTTON_BOTTOM); @@ -1343,7 +1343,7 @@ void UserInterface::summonWindow(const Surface &bgSurface) { // Gradually slide up the display of the window for (int idx = 1; idx <= bgSurface.h; idx += 2) { - screen._backBuffer.blitFrom(bgSurface, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - idx), + screen._backBuffer->blitFrom(bgSurface, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - idx), Common::Rect(0, 0, bgSurface.w, idx)); screen.slamRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - idx, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); @@ -1352,7 +1352,7 @@ void UserInterface::summonWindow(const Surface &bgSurface) { } // Final display of the entire window - screen._backBuffer.blitFrom(bgSurface, Common::Point(0, CONTROLS_Y), + screen._backBuffer->blitFrom(bgSurface, Common::Point(0, CONTROLS_Y), Common::Rect(0, 0, bgSurface.w, bgSurface.h)); screen.slamArea(0, CONTROLS_Y, bgSurface.w, bgSurface.h); @@ -1374,13 +1374,13 @@ void UserInterface::banishWindow(bool flag) { if (_windowStyle) { for (int idx = 2; idx < (SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y); idx += 2) { // Shift the window down by 2 lines - byte *pSrc = (byte *)screen._backBuffer.getBasePtr(0, CONTROLS_Y + idx - 2); - byte *pSrcEnd = (byte *)screen._backBuffer.getBasePtr(0, SHERLOCK_SCREEN_HEIGHT - 2); - byte *pDest = (byte *)screen._backBuffer.getBasePtr(0, SHERLOCK_SCREEN_HEIGHT); + byte *pSrc = (byte *)screen._backBuffer1.getBasePtr(0, CONTROLS_Y + idx - 2); + byte *pSrcEnd = (byte *)screen._backBuffer1.getBasePtr(0, SHERLOCK_SCREEN_HEIGHT - 2); + byte *pDest = (byte *)screen._backBuffer1.getBasePtr(0, SHERLOCK_SCREEN_HEIGHT); Common::copy_backward(pSrc, pSrcEnd, pDest); // Restore lines from the ui in the secondary back buffer - screen._backBuffer.blitFrom(screen._backBuffer2, + screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(0, CONTROLS_Y), Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y + idx)); @@ -1390,14 +1390,14 @@ void UserInterface::banishWindow(bool flag) { } // Restore final two old lines - screen._backBuffer.blitFrom(screen._backBuffer2, + screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - 2), Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - 2, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); screen.slamArea(0, SHERLOCK_SCREEN_HEIGHT - 2, SHERLOCK_SCREEN_WIDTH, 2); } else { // Restore old area to completely erase window - screen._backBuffer.blitFrom(screen._backBuffer2, + screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(0, CONTROLS_Y), Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, @@ -1408,7 +1408,7 @@ void UserInterface::banishWindow(bool flag) { for (int idx = 1; idx < (SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y1); idx += 2) { byte *pSrc = (byte *)screen._backBuffer2.getBasePtr(0, CONTROLS_Y1); byte *pSrcEnd = (byte *)screen._backBuffer2.getBasePtr(0, CONTROLS_Y1 + idx); - byte *pDest = (byte *)screen._backBuffer.getBasePtr(0, SHERLOCK_SCREEN_HEIGHT - idx); + byte *pDest = (byte *)screen._backBuffer1.getBasePtr(0, SHERLOCK_SCREEN_HEIGHT - idx); Common::copy(pSrc, pSrcEnd, pDest); screen.slamArea(0, SHERLOCK_SCREEN_HEIGHT - idx, SHERLOCK_SCREEN_WIDTH, -- cgit v1.2.3 From 7fec58a57d9c45f7b899f67042af57b54ca80252 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 28 Mar 2015 22:31:18 -0400 Subject: SHERLOCK: Beginnings of inventory display --- engines/sherlock/inventory.cpp | 65 ++++++++++++++++++++- engines/sherlock/inventory.h | 3 +- engines/sherlock/scene.h | 2 - engines/sherlock/screen.cpp | 18 ++++++ engines/sherlock/screen.h | 2 + engines/sherlock/user_interface.cpp | 109 +++++++++++++++++++----------------- engines/sherlock/user_interface.h | 18 ++++-- 7 files changed, 156 insertions(+), 61 deletions(-) diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index 8eb7ecc1a1..c39bba4f5b 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -31,6 +31,7 @@ Inventory::Inventory(SherlockEngine *vm) : Common::Array(), _vm(v _invIndex = 0; _holdings = 0; _oldFlag = 0; + _invFlag = 0; } Inventory::~Inventory() { @@ -129,8 +130,11 @@ void Inventory::putInv(int slamit) { * 3 = give inventory mode * 128 = Draw window in the back buffer, but don't display it */ -void Inventory::invent(int flag) { +void Inventory::drawInventory(int flag) { Screen &screen = *_vm->_screen; + UserInterface &ui = *_vm->_ui; + int tempFlag = flag; + _oldFlag = 7; loadInv(); @@ -138,7 +142,64 @@ void Inventory::invent(int flag) { screen._backBuffer = &screen._backBuffer2; } - + // Draw the window background + Surface &bb = *screen._backBuffer; + bb.fillRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y1 + 10), BORDER_COLOR); + bb.fillRect(Common::Rect(0, CONTROLS_Y1 + 10, 2, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); + bb.fillRect(Common::Rect(SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y1 + 10, + SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); + bb.fillRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - 2, SHERLOCK_SCREEN_WIDTH, + SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); + bb.fillRect(Common::Rect(2, CONTROLS_Y1 + 10, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT - 2), + INV_BACKGROUND); + + // Draw the buttons + screen.makeButton(Common::Rect(INVENTORY_POINTS[0][0], CONTROLS_Y1, INVENTORY_POINTS[0][1], + CONTROLS_Y1 + 9), INVENTORY_POINTS[0][2] - screen.stringWidth("Exit") / 2, "Exit"); + screen.makeButton(Common::Rect(INVENTORY_POINTS[1][0], CONTROLS_Y1, INVENTORY_POINTS[1][1], + CONTROLS_Y1 + 9), INVENTORY_POINTS[1][2] - screen.stringWidth("Look") / 2, "Look"); + screen.makeButton(Common::Rect(INVENTORY_POINTS[2][0], CONTROLS_Y1, INVENTORY_POINTS[2][1], + CONTROLS_Y1 + 9), INVENTORY_POINTS[2][2] - screen.stringWidth("Use") / 2, "Use"); + screen.makeButton(Common::Rect(INVENTORY_POINTS[3][0], CONTROLS_Y1, INVENTORY_POINTS[3][1], + CONTROLS_Y1 + 9), INVENTORY_POINTS[3][2] - screen.stringWidth("Give") / 2, "Give"); + screen.makeButton(Common::Rect(INVENTORY_POINTS[4][0], CONTROLS_Y1, INVENTORY_POINTS[4][1], + CONTROLS_Y1 + 9), INVENTORY_POINTS[4][2], "^^"); + screen.makeButton(Common::Rect(INVENTORY_POINTS[5][0], CONTROLS_Y1, INVENTORY_POINTS[5][1], + CONTROLS_Y1 + 9), INVENTORY_POINTS[5][2], "^"); + screen.makeButton(Common::Rect(INVENTORY_POINTS[6][0], CONTROLS_Y1, INVENTORY_POINTS[6][1], + CONTROLS_Y1 + 9), INVENTORY_POINTS[6][2], "_"); + screen.makeButton(Common::Rect(INVENTORY_POINTS[7][0], CONTROLS_Y1, INVENTORY_POINTS[7][1], + CONTROLS_Y1 + 9), INVENTORY_POINTS[7][2], "__"); + + if (tempFlag == 128) + flag = 1; + ui._invMode = flag; + + if (flag) { + ui._oldKey = INVENTORY_COMMANDS[flag]; + _oldFlag = flag; + } else { + ui._oldKey = -1; + _invFlag = 6; + } + + invCommands(0); + putInv(0); + + if (tempFlag != 128) { + if (!ui._windowStyle) { + screen.slamRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + } else { + ui.summonWindow(false, CONTROLS_Y1); + } + + ui._windowOpen = true; + } else { + // Reset the screen back buffer to the first buffer now that drawing is done + screen._backBuffer = &screen._backBuffer1; + } + + ui._oldUse = -1; } void Inventory::invCommands(bool slamIt) { diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index 1db91292a5..7785250e8c 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -51,6 +51,7 @@ public: int _holdings; void freeGraphics(); int _oldFlag; + int _invFlag; public: Inventory(SherlockEngine *vm); ~Inventory(); @@ -65,7 +66,7 @@ public: void putInv(int slamit); - void invent(int flag); + void drawInventory(int flag); void invCommands(bool slamIt); diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 007f910b10..d89a47e560 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -34,8 +34,6 @@ namespace Sherlock { #define SCENES_COUNT 63 #define MAX_ZONES 40 #define INFO_LINE 140 -#define CONTROLS_Y 138 -#define CONTROLS_Y1 151 enum InvMode { INVMODE_0 = 0, diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index f1562e2468..16d590c0f4 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -409,4 +409,22 @@ void Screen::vgaBar(const Common::Rect &r, int color) { slamRect(r); } +/** + * Draws a button for use in the inventory, talk, and examine dialogs. + */ +void Screen::makeButton(const Common::Rect &bounds, int textX, + const Common::String &str) { + + Surface &bb = *_backBuffer; + bb.fillRect(Common::Rect(bounds.left, bounds.top, bounds.right, bounds.top + 1), BUTTON_TOP); + bb.fillRect(Common::Rect(bounds.left, bounds.top, bounds.left + 1, bounds.bottom), BUTTON_TOP); + bb.fillRect(Common::Rect(bounds.right - 1, bounds.top, bounds.right, bounds.bottom), BUTTON_BOTTOM); + bb.fillRect(Common::Rect(bounds.left + 1, bounds.bottom - 1, bounds.right, bounds.bottom), BUTTON_BOTTOM); + bb.fillRect(Common::Rect(bounds.left + 1, bounds.top + 1, bounds.right - 1, bounds.bottom - 1), BUTTON_MIDDLE); + + gPrint(Common::Point(textX, bounds.top), COMMAND_HIGHLIGHTED, "%c", str[0]); + gPrint(Common::Point(textX + charWidth(str[0]), bounds.top), + COMMAND_FOREGROUND, "%s", str.c_str() + 1); +} + } // End of namespace Sherlock diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 7d07cfa062..f33bbfceab 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -112,6 +112,8 @@ public: int charWidth(char c); void vgaBar(const Common::Rect &r, int color); + + void makeButton(const Common::Rect &bounds, int textX, const Common::String &str); }; } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index dbc9108212..a993965429 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -54,6 +54,7 @@ const int INVENTORY_POINTS[8][3] = { }; const char COMMANDS[13] = "LMTPOCIUGJFS"; +const char INVENTORY_COMMANDS[9] = { "ELUG-+,." }; const char *const PRESS_KEY_FOR_MORE = "Press any Key for More."; const char *const PRESS_KEY_TO_CONTINUE = "Press any Key to Continue."; @@ -85,6 +86,7 @@ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { SHERLOCK_SCREEN_HEIGHT - 1); _windowStyle = 1; // Sliding windows _find = 0; + _oldUse = 0; } UserInterface::~UserInterface() { @@ -686,7 +688,6 @@ void UserInterface::doInvControl() { Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; Talk &talk = *_vm->_talk; - const char INVENTORY_COMMANDS[9] = { "ELUG-+,." }; int colors[8]; Common::Point mousePos = events.mousePos(); @@ -956,7 +957,7 @@ void UserInterface::doLookControl() { tempSurface.blitFrom(screen._backBuffer2, Common::Point(0, 0), Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); - inv.invent(128); + inv.drawInventory(128); banishWindow(true); // Restore the ui @@ -1060,19 +1061,19 @@ void UserInterface::doMainControl() { pushButton(6); _selector = _oldSelector = -1; _menuMode = INV_MODE; - inv.invent(1); + inv.drawInventory(1); break; case 'U': pushButton(7); _selector = _oldSelector = -1; _menuMode = USE_MODE; - inv.invent(2); + inv.drawInventory(2); break; case 'G': pushButton(8); _selector = _oldSelector = -1; _menuMode = GIVE_MODE; - inv.invent(3); + inv.drawInventory(3); break; case 'J': pushButton(9); @@ -1259,7 +1260,7 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { // Handle display depending on whether all the message was shown if (!endOfStr) { - makeButton(Common::Rect(46, CONTROLS_Y, 272, CONTROLS_Y + 10), + screen.makeButton(Common::Rect(46, CONTROLS_Y, 272, CONTROLS_Y + 10), (SHERLOCK_SCREEN_WIDTH - screen.stringWidth(PRESS_KEY_FOR_MORE)) / 2, PRESS_KEY_FOR_MORE); screen.gPrint(Common::Point((SHERLOCK_SCREEN_WIDTH - @@ -1267,7 +1268,7 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { COMMAND_FOREGROUND, "P"); _descStr = msgP; } else { - makeButton(Common::Rect(46, CONTROLS_Y, 272, CONTROLS_Y + 10), + screen.makeButton(Common::Rect(46, CONTROLS_Y, 272, CONTROLS_Y + 10), (SHERLOCK_SCREEN_WIDTH - screen.stringWidth(PRESS_KEY_TO_CONTINUE)) / 2, PRESS_KEY_TO_CONTINUE); screen.gPrint(Common::Point((SHERLOCK_SCREEN_WIDTH - @@ -1280,20 +1281,9 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { if (!_windowStyle) { screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); - } - else { - // Extract the window that's been drawn on the back buffer - Surface tempSurface(SHERLOCK_SCREEN_WIDTH, - (SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y)); - Common::Rect r(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); - tempSurface.blitFrom(screen._backBuffer1, Common::Point(0, 0), r); - - // Remove drawn window with original user interface - screen._backBuffer1.blitFrom(screen._backBuffer2, - Common::Point(0, CONTROLS_Y), r); - - // Display the window gradually on-screen - summonWindow(tempSurface); + } else { + // Display the window + summonWindow(); } _selector = _oldSelector = -1; @@ -1311,29 +1301,10 @@ void UserInterface::printObjectDesc() { printObjectDesc(_cAnimStr, true); } -/** - * Draws a button for use in the inventory, talk, and examine dialogs. - */ -void UserInterface::makeButton(const Common::Rect &bounds, int textX, - const Common::String &str) { - Screen &screen = *_vm->_screen; - - Surface &bb = *screen._backBuffer; - bb.fillRect(Common::Rect(bounds.left, bounds.top, bounds.right, bounds.top + 1), BUTTON_TOP); - bb.fillRect(Common::Rect(bounds.left, bounds.top, bounds.left + 1, bounds.bottom), BUTTON_TOP); - bb.fillRect(Common::Rect(bounds.right - 1, bounds.top, bounds.right, bounds.bottom), BUTTON_BOTTOM); - bb.fillRect(Common::Rect(bounds.left + 1, bounds.bottom - 1, bounds.right, bounds.bottom), BUTTON_BOTTOM); - bb.fillRect(Common::Rect(bounds.left + 1, bounds.top + 1, bounds.right - 1, bounds.bottom - 1), BUTTON_MIDDLE); - - screen.gPrint(Common::Point(textX, bounds.top), COMMAND_HIGHLIGHTED, "%c", str[0]); - screen.gPrint(Common::Point(textX + screen.charWidth(str[0]), bounds.top), - COMMAND_FOREGROUND, "%s", str.c_str() + 1); -} - /** * Displays a passed window by gradually scrolling it vertically on-screen */ -void UserInterface::summonWindow(const Surface &bgSurface) { +void UserInterface::summonWindow(const Surface &bgSurface, bool slideUp) { Events &events = *_vm->_events; Screen &screen = *_vm->_screen; @@ -1341,34 +1312,68 @@ void UserInterface::summonWindow(const Surface &bgSurface) { // A window is already open, so can't open another one return; - // Gradually slide up the display of the window - for (int idx = 1; idx <= bgSurface.h; idx += 2) { - screen._backBuffer->blitFrom(bgSurface, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - idx), - Common::Rect(0, 0, bgSurface.w, idx)); - screen.slamRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - idx, - SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + if (slideUp) { + // Gradually slide up the display of the window + for (int idx = 1; idx <= bgSurface.h; idx += 2) { + screen._backBuffer->blitFrom(bgSurface, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - idx), + Common::Rect(0, 0, bgSurface.w, idx)); + screen.slamRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - idx, + SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); - events.delay(10); + events.delay(10); + } + } else { + // Gradually slide down the display of the window + for (int idx = 1; idx <= bgSurface.h; idx += 2) { + screen._backBuffer->blitFrom(bgSurface, + Common::Point(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h), + Common::Rect(0, bgSurface.h - idx, bgSurface.w, bgSurface.h)); + screen.slamRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h, + SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT - bgSurface.h + idx)); + + events.delay(10); + } } // Final display of the entire window - screen._backBuffer->blitFrom(bgSurface, Common::Point(0, CONTROLS_Y), + screen._backBuffer->blitFrom(bgSurface, Common::Point(0, + SHERLOCK_SCREEN_HEIGHT - bgSurface.h), Common::Rect(0, 0, bgSurface.w, bgSurface.h)); - screen.slamArea(0, CONTROLS_Y, bgSurface.w, bgSurface.h); + screen.slamArea(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h, bgSurface.w, bgSurface.h); _windowOpen = true; } +/** + * Slide the window stored in the back buffer onto the screen + */ +void UserInterface::summonWindow(bool slideUp, int height) { + Screen &screen = *_vm->_screen; + + // Extract the window that's been drawn on the back buffer + Surface tempSurface(SHERLOCK_SCREEN_WIDTH, + (SHERLOCK_SCREEN_HEIGHT - height)); + Common::Rect r(0, height, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + tempSurface.blitFrom(screen._backBuffer1, Common::Point(0, 0), r); + + // Remove drawn window with original user interface + screen._backBuffer1.blitFrom(screen._backBuffer2, + Common::Point(0, height), r); + + // Display the window gradually on-screen + summonWindow(tempSurface, slideUp); +} + /** * Close a currently open window * @param flag 0 = slide old window down, 1 = slide prior UI back up */ -void UserInterface::banishWindow(bool flag) { +void UserInterface::banishWindow(bool slideUp) { Events &events = *_vm->_events; Screen &screen = *_vm->_screen; if (_windowOpen) { - if (flag || !_windowStyle) { + if (slideUp || !_windowStyle) { // Slide window down // Only slide the window if the window style allows it if (_windowStyle) { diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index d94b2fadc5..87fd4a5e99 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -31,6 +31,9 @@ namespace Sherlock { +#define CONTROLS_Y 138 +#define CONTROLS_Y1 151 + enum MenuMode { STD_MODE = 0, LOOK_MODE = 1, @@ -47,9 +50,16 @@ enum MenuMode { SETUP_MODE = 12 }; +extern const int MENU_POINTS[12][4]; + +extern const int INVENTORY_POINTS[8][3]; +extern const char INVENTORY_COMMANDS[9]; + class SherlockEngine; +class Inventory; class UserInterface { + friend class Inventory; private: SherlockEngine *_vm; ImageFile *_controlPanel; @@ -77,6 +87,7 @@ private: int _windowStyle; int _find; Common::String _muse; + int _oldUse; private: void depressButton(int num); @@ -106,8 +117,6 @@ private: void environment(); void doControls(); - void makeButton(const Common::Rect &bounds, int textX, const Common::String &str); - void checkUseAction(UseType &use, const Common::String &invName, const Common::String &msg, int objNum, int giveMode); public: @@ -132,8 +141,9 @@ public: void printObjectDesc(const Common::String &str, bool firstTime); void printObjectDesc(); - void summonWindow(const Surface &bgSurface); - void banishWindow(bool flag); + void summonWindow(const Surface &bgSurface, bool slideUp = true); + void summonWindow(bool slideUp = true, int height = CONTROLS_Y); + void banishWindow(bool slideUp = true); }; } // End of namespace Sherlock -- cgit v1.2.3 From 3149ce0204f658e7420f16a151710f43052506f2 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 29 Mar 2015 09:52:23 -0400 Subject: SHERLOCK: Added inventory list and display images in inventory mode --- engines/sherlock/inventory.cpp | 149 ++++++++++++++++++++++++++++++++--- engines/sherlock/inventory.h | 6 +- engines/sherlock/scalpel/scalpel.cpp | 25 ++++++ engines/sherlock/scalpel/scalpel.h | 2 + engines/sherlock/screen.cpp | 47 ++++++++++- engines/sherlock/screen.h | 12 ++- engines/sherlock/user_interface.cpp | 86 ++++++++++---------- engines/sherlock/user_interface.h | 4 - 8 files changed, 262 insertions(+), 69 deletions(-) diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index c39bba4f5b..a7691fc866 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -25,6 +25,14 @@ namespace Sherlock { +InventoryItem::InventoryItem(int requiredFlag, const Common::String &name, + const Common::String &description, const Common::String &examine) : + _requiredFlag(requiredFlag), _name(name), _description(description), + _examine(examine), _lookFlag(0) { +} + +/*----------------------------------------------------------------*/ + Inventory::Inventory(SherlockEngine *vm) : Common::Array(), _vm(vm) { Common::fill(&_invShapes[0], &_invShapes[MAX_VISIBLE_INVENTORY], (ImageFile *)nullptr); _invGraphicsLoaded = false; @@ -32,6 +40,7 @@ Inventory::Inventory(SherlockEngine *vm) : Common::Array(), _vm(v _holdings = 0; _oldFlag = 0; _invFlag = 0; + _invMode = 0; } Inventory::~Inventory() { @@ -77,6 +86,8 @@ void Inventory::loadInv() { } delete stream; + + loadGraphics(); } /** @@ -89,11 +100,11 @@ void Inventory::loadGraphics() { // Default all inventory slots to empty Common::fill(&_invShapes[0], &_invShapes[MAX_VISIBLE_INVENTORY], (ImageFile *)nullptr); - for (int idx = _invIndex; (idx < _holdings) && (idx - _invIndex) < 6; ++idx) { + for (int idx = _invIndex; (idx < _holdings) && (idx - _invIndex) < MAX_VISIBLE_INVENTORY; ++idx) { // Get the name of the item to be dispalyed, figure out it's accompanying // .VGS file with it's picture, and then load it int invNum = findInv((*this)[idx]._name); - Common::String fName = Common::String::format("item%02d.vgs", invNum); + Common::String fName = Common::String::format("item%02d.vgs", invNum + 1); _invShapes[idx] = new ImageFile(fName); } @@ -106,20 +117,73 @@ void Inventory::loadGraphics() { * and returns the numer that matches the passed name */ int Inventory::findInv(const Common::String &name) { - int result = -1; - - for (int idx = 0; (idx < _holdings) && result == -1; ++idx) { + for (int idx = 0; idx < size(); ++idx) { if (scumm_stricmp(name.c_str(), _names[idx].c_str()) == 0) - result = idx; + return idx; } - if (result == -1) - result = 1; - return result; + return 1; } -void Inventory::putInv(int slamit) { - // TODO +/** + * Display the character's inventory. The slamIt parameter specifies: + * 0 = Draw it on the back buffer, and don't display it + * 1 = Draw it on the back buffer, and then display it + * 2 = Draw it on the secondary back buffer, and don't display it + */ +void Inventory::putInv(int slamIt) { + Screen &screen = *_vm->_screen; + UserInterface &ui = *_vm->_ui; + + // If an inventory item has disappeared (due to using it or giving it), + // a blank space slot may haave appeared. If so, adjust the inventory + if (_invIndex > 0 && _invIndex > (_holdings - 6)) { + --_invIndex; + freeGraphics(); + loadGraphics(); + } + + if (slamIt != 2) { + screen.makePanel(Common::Rect(6, 163, 54, 197)); + screen.makePanel(Common::Rect(58, 163, 106, 197)); + screen.makePanel(Common::Rect(110, 163, 158, 197)); + screen.makePanel(Common::Rect(162, 163, 210, 197)); + screen.makePanel(Common::Rect(214, 163, 262, 197)); + screen.makePanel(Common::Rect(266, 163, 314, 197)); + } + + // Iterate through displaying up to 6 objects at a time + for (int idx = _invIndex; idx < _holdings && (idx - _invIndex) < MAX_VISIBLE_INVENTORY; ++idx) { + int itemNum = idx - _invIndex; + Surface &bb = slamIt == 2 ? screen._backBuffer2 : screen._backBuffer1; + Common::Rect r(8 + itemNum * 52, 165, 51 + itemNum * 52, 194); + + // Draw the background + if (idx == ui._selector) { + bb.fillRect(r, 235); + } else if (slamIt == 2) { + bb.fillRect(r, BUTTON_MIDDLE); + } + + // Draw the item image + Graphics::Surface &img = (*_invShapes[itemNum])[0]._frame; + bb.transBlitFrom(img, Common::Point(6 + itemNum * 52 + ((47 - img.w) / 2), + 163 + ((33 - img.h) / 2))); + } + + if (slamIt == 1) + screen.slamArea(6, 163, 308, 34); + + if (slamIt != 2) + ui.clearInfo(); + + if (slamIt == 0) { + invCommands(0); + } else if (slamIt == 2) { + screen._backBuffer = &screen._backBuffer2; + invCommands(0); + screen._backBuffer = &screen._backBuffer1; + } } /** @@ -173,7 +237,7 @@ void Inventory::drawInventory(int flag) { if (tempFlag == 128) flag = 1; - ui._invMode = flag; + _invMode = flag; if (flag) { ui._oldKey = INVENTORY_COMMANDS[flag]; @@ -202,8 +266,67 @@ void Inventory::drawInventory(int flag) { ui._oldUse = -1; } +/** + * Prints the line of inventory commands at the top of an inventory window with + * the correct highlighting + */ void Inventory::invCommands(bool slamIt) { - // TODO + Screen &screen = *_vm->_screen; + UserInterface &ui = *_vm->_ui; + + if (slamIt) { + screen.buttonPrint(Common::Point(INVENTORY_POINTS[0][2], CONTROLS_Y1), + _invMode == 0 ? COMMAND_HIGHLIGHTED :COMMAND_FOREGROUND, + true, "Exit"); + screen.buttonPrint(Common::Point(INVENTORY_POINTS[1][2], CONTROLS_Y1), + _invMode == 1 ? COMMAND_HIGHLIGHTED :COMMAND_FOREGROUND, + true, "Look"); + screen.buttonPrint(Common::Point(INVENTORY_POINTS[2][2], CONTROLS_Y1), + _invMode == 2 ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, + true, "Use"); + screen.buttonPrint(Common::Point(INVENTORY_POINTS[3][2], CONTROLS_Y1), + _invMode == 3 ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, + true, "Give"); + screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1), + _invMode == 0 ? COMMAND_NULL : COMMAND_FOREGROUND, + "^^"); + screen.print(Common::Point(INVENTORY_POINTS[5][2], CONTROLS_Y1 + 1), + _invMode == 0 ? COMMAND_NULL : COMMAND_FOREGROUND, + "^"); + screen.print(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1 + 1), + (_holdings - _invIndex <= 6) ? COMMAND_NULL : COMMAND_FOREGROUND, + "_"); + screen.print(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1 + 1), + (_holdings - _invIndex <= 6) ? COMMAND_NULL : COMMAND_FOREGROUND, + "__"); + if (_invMode != 1) + ui.clearInfo(); + } else { + screen.buttonPrint(Common::Point(INVENTORY_POINTS[0][2], CONTROLS_Y1), + _invMode == 0 ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, + false, "Exit"); + screen.buttonPrint(Common::Point(INVENTORY_POINTS[1][2], CONTROLS_Y1), + _invMode == 1 ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, + false, "Look"); + screen.buttonPrint(Common::Point(INVENTORY_POINTS[2][2], CONTROLS_Y1), + _invMode == 2 ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, + false, "Use"); + screen.buttonPrint(Common::Point(INVENTORY_POINTS[3][2], CONTROLS_Y1), + _invMode == 3 ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, + false, "Give"); + screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1), + _invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND, + "^^"); + screen.print(Common::Point(INVENTORY_POINTS[5][2], CONTROLS_Y1), + _invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND, + "^"); + screen.print(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1), + (_holdings - _invIndex < 7) ? COMMAND_NULL : COMMAND_FOREGROUND, + "_"); + screen.print(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1), + (_holdings - _invIndex < 7) ? COMMAND_NULL : COMMAND_FOREGROUND, + "__"); + } } void Inventory::doInvLite(int index, byte color) { diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index 7785250e8c..e9a4ba5548 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -38,6 +38,9 @@ struct InventoryItem { Common::String _description;; Common::String _examine; int _lookFlag; + + InventoryItem(int requiredFlag, const Common::String &name, + const Common::String &description, const Common::String &examine); }; class Inventory : public Common::Array { @@ -47,6 +50,7 @@ public: ImageFile *_invShapes[MAX_VISIBLE_INVENTORY]; Common::StringArray _names; bool _invGraphicsLoaded; + int _invMode; int _invIndex; int _holdings; void freeGraphics(); @@ -64,7 +68,7 @@ public: int findInv(const Common::String &name); - void putInv(int slamit); + void putInv(int slamIt); void drawInventory(int flag); diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index db59434f85..d226c2e82a 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -68,6 +68,9 @@ void ScalpelEngine::initialize() { for (int idx = 0; idx < NUM_PLACES; ++idx) _map.push_back(Common::Point(MAP_X[idx], MAP_Y[idx])); + // Load the inventory + loadInventory(); + // Starting scene _scene->_goToScene = 4; } @@ -176,6 +179,28 @@ bool ScalpelEngine::showOfficeCutscene() { return true; } +void ScalpelEngine::loadInventory() { + Inventory &inv = *_inventory; + + // Initial inventory + inv._holdings = 2; + inv.push_back(InventoryItem(0, "Message", "A message requesting help", "_ITEM03A")); + inv.push_back(InventoryItem(0, "Holmes Card", "A number of business cards", "_ITEM07A")); + + // Potential items + inv.push_back(InventoryItem(95, "Tickets", "Opera Tickets", "_ITEM10A")); + inv.push_back(InventoryItem(138, "Cuff Link", "Cuff Link", "_ITEM04A")); + inv.push_back(InventoryItem(138, "Wire Hook", "Wire Hook", "_ITEM06A")); + inv.push_back(InventoryItem(150, "Note", "Note", "_ITEM13A")); + inv.push_back(InventoryItem(481, "Open Watch", "An open pocket watch", "_ITEM62A")); + inv.push_back(InventoryItem(481, "Paper", "A piece of paper with numbers on it", "_ITEM44A")); + inv.push_back(InventoryItem(532, "Letter", "A letter folded many times", "_ITEM68A")); + inv.push_back(InventoryItem(544, "Tarot", "Tarot Cards", "_ITEM71A")); + inv.push_back(InventoryItem(544, "Ornate Key", "An ornate key", "_ITEM70A")); + inv.push_back(InventoryItem(586, "Pawn ticket", "A pawn ticket", "_ITEM16A")); +}; + + /** * Starting a scene within the game */ diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h index caf33052aa..34d017e757 100644 --- a/engines/sherlock/scalpel/scalpel.h +++ b/engines/sherlock/scalpel/scalpel.h @@ -41,6 +41,8 @@ private: bool showAlleyCutscene(); bool showStreetCutscene(); bool showOfficeCutscene(); + + void loadInventory(); protected: virtual void initialize(); diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 16d590c0f4..a3705b54da 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -310,7 +310,7 @@ void Screen::flushImage(ImageFrame *frame, const Common::Point &pt, * Prints the text passed onto the back buffer at the given position and color. * The string is then blitted to the screen */ -void Screen::print(const Common::Point &pt, int color, const char *format, ...) { +void Screen::print(const Common::Point &pt, byte color, const char *format, ...) { // Create the string to display char buffer[100]; va_list args; @@ -344,7 +344,7 @@ void Screen::print(const Common::Point &pt, int color, const char *format, ...) /** * Print a strings onto the back buffer without blitting it to the screen */ -void Screen::gPrint(const Common::Point &pt, int color, const char *format, ...) { +void Screen::gPrint(const Common::Point &pt, byte color, const char *format, ...) { // Create the string to display char buffer[100]; va_list args; @@ -386,7 +386,7 @@ int Screen::charWidth(char c) { /** * Draws the given string into the back buffer using the images stored in _font */ -void Screen::writeString(const Common::String &str, const Common::Point &pt, int color) { +void Screen::writeString(const Common::String &str, const Common::Point &pt, byte color) { Common::Point charPos = pt; for (const char *c = str.c_str(); *c; ++c) { @@ -427,4 +427,45 @@ void Screen::makeButton(const Common::Rect &bounds, int textX, COMMAND_FOREGROUND, "%s", str.c_str() + 1); } +/** + * Prints an interface command with the first letter highlighted to indicate + * what keyboard shortcut is associated with it + */ +void Screen::buttonPrint(const Common::Point &pt, byte color, bool slamIt, + const Common::String &str) { + int xStart = pt.x - stringWidth(str) / 2; + + if (color == COMMAND_FOREGROUND) { + // First character needs to be highlighted + if (slamIt) { + print(Common::Point(xStart, pt.y + 1), COMMAND_HIGHLIGHTED, "%c", str[0]); + print(Common::Point(xStart + charWidth(str[0]), pt.y + 1), + color, "%s", str.c_str() + 1); + } else { + print(Common::Point(xStart, pt.y), COMMAND_HIGHLIGHTED, "%c", str[0]); + print(Common::Point(xStart + charWidth(str[0]), pt.y), + color, "%s", str.c_str() + 1); + } + } else { + print(Common::Point(xStart, slamIt ? pt.y + 1 : pt.y), COMMAND_HIGHLIGHTED, + "%s", str.c_str()); + } +} + +/** + * Draw a panel in th eback buffer with a raised area effect around the edges + */ +void Screen::makePanel(const Common::Rect &r) { + _backBuffer->fillRect(r, BUTTON_MIDDLE); + _backBuffer->hLine(r.left, r.top, r.right - 2, BUTTON_TOP); + _backBuffer->hLine(r.left + 1, r.top + 1, r.right - 3, BUTTON_TOP); + _backBuffer->vLine(r.left, r.top, r.bottom - 1, BUTTON_TOP); + _backBuffer->vLine(r.left + 1, r.top + 1, r.bottom - 2, BUTTON_TOP); + + _backBuffer->vLine(r.right - 1, r.top, r.bottom - 1, BUTTON_BOTTOM); + _backBuffer->vLine(r.right - 2, r.top + 1, r.bottom - 2, BUTTON_BOTTOM); + _backBuffer->hLine(r.left, r.bottom - 1, r.right - 1, BUTTON_BOTTOM); + _backBuffer->hLine(r.left + 1, r.bottom - 2, r.right - 1, BUTTON_BOTTOM); +} + } // End of namespace Sherlock diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index f33bbfceab..5047d40216 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -44,6 +44,8 @@ enum { INV_BACKGROUND = 1, COMMAND_HIGHLIGHTED = 10, COMMAND_FOREGROUND = 15, + COMMAND_BACKGROUND = 4, + COMMAND_NULL = 248, BUTTON_TOP = 233, BUTTON_MIDDLE = 244, BUTTON_BOTTOM = 248, @@ -65,7 +67,7 @@ private: bool unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2); - void writeString(const Common::String &str, const Common::Point &pt, int color); + void writeString(const Common::String &str, const Common::Point &pt, byte color); protected: virtual void addDirtyRect(const Common::Rect &r); public: @@ -96,8 +98,8 @@ public: void verticalTransition(); - void print(const Common::Point &pt, int color, const char *format, ...); - void gPrint(const Common::Point &pt, int color, const char *format, ...); + void print(const Common::Point &pt, byte color, const char *format, ...); + void gPrint(const Common::Point &pt, byte color, const char *format, ...); void restoreBackground(const Common::Rect &r); @@ -114,6 +116,10 @@ public: void vgaBar(const Common::Rect &r, int color); void makeButton(const Common::Rect &bounds, int textX, const Common::String &str); + + void buttonPrint(const Common::Point &pt, byte color, bool slamIt, const Common::String &str); + + void makePanel(const Common::Rect &r); }; } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index a993965429..5e8b3287f0 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -77,8 +77,6 @@ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { _windowOpen = false; _oldLook = false; _keyboardInput = false; - _invMode = 0; - _invIndex = 0; _pause = false; _cNum = 0; _selector = _oldSelector = -1; @@ -116,6 +114,7 @@ void UserInterface::drawInterface() { */ void UserInterface::handleInput() { Events &events = *_vm->_events; + Inventory &inv = *_vm->_inventory; People &people = *_vm->_people; Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; @@ -276,7 +275,7 @@ void UserInterface::handleInput() { case USE_MODE: case GIVE_MODE: case INV_MODE: - if (_invMode == 1 || _invMode == 2 || _invMode == 3) { + if (inv._invMode == 1 || inv._invMode == 2 || inv._invMode == 3) { if (pt.y < CONTROLS_Y) lookInv(); else @@ -455,11 +454,6 @@ void UserInterface::toggleButton(int num) { } } -void UserInterface::buttonPrint(const Common::Point &pt, int color, bool slamIt, - const Common::String &str) { - // TODO -} - /** * Clears the info line of the screen */ @@ -566,10 +560,10 @@ void UserInterface::lookScreen(const Common::Point &pt) { if (!tempStr.empty() && tempStr[0] != ' ') { // If inventory is active and an item is selected for a Use or Give action if ((_menuMode == INV_MODE || _menuMode == USE_MODE || _menuMode == GIVE_MODE) && - (_invMode == 2 || _invMode == 3)) { + (inv._invMode == 2 || inv._invMode == 3)) { width1 = screen.stringWidth(inv[_selector]._name); - if (_invMode == 2) { + if (inv._invMode == 2) { // Using an object x = width = screen.stringWidth("Use "); @@ -658,7 +652,7 @@ void UserInterface::lookInv() { if (mousePos.x > 15 && mousePos.x < 314 && mousePos.y > (CONTROLS_Y1 + 11) && mousePos.y < (SHERLOCK_SCREEN_HEIGHT - 2)) { - int temp = (mousePos.x - 6) / 52 + _invIndex; + int temp = (mousePos.x - 6) / 52 + inv._invIndex; if (temp < inv._holdings) { if (temp < inv._holdings) { clearInfo(); @@ -712,25 +706,25 @@ void UserInterface::doInvControl() { if (found != -1) // If a slot highlighted, set it's color colors[found] = COMMAND_HIGHLIGHTED; - buttonPrint(Common::Point(INVENTORY_POINTS[0][2], CONTROLS_Y1), + screen.buttonPrint(Common::Point(INVENTORY_POINTS[0][2], CONTROLS_Y1), colors[0], true, "Exit"); if (found >= 0 && found <= 3) { - buttonPrint(Common::Point(INVENTORY_POINTS[1][2], CONTROLS_Y1), colors[1], true, "Look"); - buttonPrint(Common::Point(INVENTORY_POINTS[2][2], CONTROLS_Y1), colors[1], true, "Use"); - buttonPrint(Common::Point(INVENTORY_POINTS[3][2], CONTROLS_Y1), colors[1], true, "Give"); - _invMode = found; + screen.buttonPrint(Common::Point(INVENTORY_POINTS[1][2], CONTROLS_Y1), colors[1], true, "Look"); + screen.buttonPrint(Common::Point(INVENTORY_POINTS[2][2], CONTROLS_Y1), colors[1], true, "Use"); + screen.buttonPrint(Common::Point(INVENTORY_POINTS[3][2], CONTROLS_Y1), colors[1], true, "Give"); + inv._invMode = found; _selector = -1; } - if (_invIndex) { + if (inv._invIndex) { screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1), colors[4], "^^"); screen.print(Common::Point(INVENTORY_POINTS[5][2], CONTROLS_Y1 + 1), colors[5], "^"); } - if ((inv._holdings - _invIndex) > 6) { + if ((inv._holdings - inv._invIndex) > 6) { screen.print(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1 + 1), colors[6], "^^"); screen.print(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1 + 1), @@ -738,7 +732,7 @@ void UserInterface::doInvControl() { } bool flag = false; - if (_invMode == 1 || _invMode == 2 || _invMode == 3) { + if (inv._invMode == 1 || inv._invMode == 2 || inv._invMode == 3) { Common::Rect r(15, CONTROLS_Y1 + 11, 314, SHERLOCK_SCREEN_HEIGHT - 2); flag = (_selector < inv._holdings); } @@ -756,16 +750,16 @@ void UserInterface::doInvControl() { if (_key == 'E' || _key == 'L' || _key == 'U' || _key == 'G' || _key == '-' || _key == '+') { - int temp = _invMode; + int temp = inv._invMode; const char *chP = strchr(INVENTORY_COMMANDS, _key); - _invMode = !chP ? 8 : chP - INVENTORY_COMMANDS; + inv._invMode = !chP ? 8 : chP - INVENTORY_COMMANDS; inv.invCommands(true); - _invMode = temp; + inv._invMode = temp; _keyboardInput = true; if (_key == 'E') - _invMode = STD_MODE; + inv._invMode = STD_MODE; _selector = -1; } else { _selector = -1; @@ -775,7 +769,7 @@ void UserInterface::doInvControl() { if (_selector != _oldSelector) { if (_oldSelector != -1) { // Un-highlight - if (_oldSelector >= _invIndex && _oldSelector < (_invIndex + 6)) + if (_oldSelector >= inv._invIndex && _oldSelector < (inv._invIndex + 6)) inv.doInvLite(_oldSelector, BUTTON_MIDDLE); } @@ -795,16 +789,16 @@ void UserInterface::doInvControl() { events.clearEvents(); events.setCursor(ARROW); } else if ((found == 1 && events._released) || (_key == 'L')) { - _invMode = 1; + inv._invMode = 1; } else if ((found == 2 && events._released) || (_key == 'U')) { - _invMode = 2; + inv._invMode = 2; } else if ((found == 3 && events._released) || (_key == 'G')) { - _invMode = 3; - } else if (((found == 4 && events._released) || _key == ',') && _invIndex) { - if (_invIndex >= 6) - _invIndex -= 6; + inv._invMode = 3; + } else if (((found == 4 && events._released) || _key == ',') && inv._invIndex) { + if (inv._invIndex >= 6) + inv._invIndex -= 6; else - _invIndex = 0; + inv._invIndex = 0; screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1), COMMAND_HIGHLIGHTED, "^^"); @@ -812,26 +806,28 @@ void UserInterface::doInvControl() { inv.loadGraphics(); inv.putInv(1); inv.invCommands(true); - } else if (((found == 5 && events._released) || _key == '-') && _invIndex) { - --_invIndex; + } else if (((found == 5 && events._released) || _key == '-') && inv._invIndex) { + --inv._invIndex; screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1), COMMAND_HIGHLIGHTED, "^"); inv.freeGraphics(); inv.loadGraphics(); inv.putInv(1); inv.invCommands(true); - } else if (((found == 6 && events._released) || _key == '+') && (inv._holdings - _invIndex) > 6) { - ++_invIndex; + } else if (((found == 6 && events._released) || _key == '+') && + (inv._holdings - inv._invIndex) > 6) { + ++inv._invIndex; screen.print(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1 + 1), COMMAND_HIGHLIGHTED, "_"); inv.freeGraphics(); inv.loadGraphics(); inv.putInv(1); inv.invCommands(true); - } else if (((found == 7 && events._released) || _key == '.') && (inv._holdings - _invIndex) > 6) { - _invIndex += 6; - if ((inv._holdings - 6) < _invIndex) - _invIndex = inv._holdings - 6; + } else if (((found == 7 && events._released) || _key == '.') && + (inv._holdings - inv._invIndex) > 6) { + inv._invIndex += 6; + if ((inv._holdings - 6) < inv._invIndex) + inv._invIndex = inv._holdings - 6; screen.print(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1 + 1), COMMAND_HIGHLIGHTED, "_"); @@ -841,7 +837,7 @@ void UserInterface::doInvControl() { inv.invCommands(true); } else { // If something is being given, make sure it's to a person - if (_invMode == 3) { + if (inv._invMode == 3) { if (_bgFound != -1 && scene._bgShapes[_bgFound]._aType == PERSON) _find = _bgFound; else @@ -850,7 +846,7 @@ void UserInterface::doInvControl() { _find = _bgFound; } - if ((mousePos.y < CONTROLS_Y1) && (_invMode == 1) && (_find >= 0) && (_find < 1000)) { + if ((mousePos.y < CONTROLS_Y1) && (inv._invMode == 1) && (_find >= 0) && (_find < 1000)) { if (!scene._bgShapes[_find]._examine.empty() && scene._bgShapes[_find]._examine[0] >= ' ') inv.doInvJF(); @@ -859,7 +855,7 @@ void UserInterface::doInvControl() { // If it's -1, then no inventory item is highlighted yet. Otherwise, // an object in the scene has been clicked. - if (_selector != -1 && _invMode == 1 && mousePos.y >(CONTROLS_Y1 + 11)) + if (_selector != -1 && inv._invMode == 1 && mousePos.y >(CONTROLS_Y1 + 11)) inv.doInvJF(); if (talk._talkToAbort) @@ -872,7 +868,7 @@ void UserInterface::doInvControl() { // is being tried on an object in the scene without an inventory // object being highlighted first. - if ((_invMode == 2 || (_selector != -1 && _invMode == 3)) && _find >= 0) { + if ((inv._invMode == 2 || (_selector != -1 && inv._invMode == 3)) && _find >= 0) { events._pressed = events._released = false; _infoFlag = true; clearInfo(); @@ -882,8 +878,8 @@ void UserInterface::doInvControl() { inv.putInv(1); _selector = temp; // Restore it - temp = _invMode; - _invMode = -1; + temp = inv._invMode; + inv._invMode = -1; inv.invCommands(true); _infoFlag = true; diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index 87fd4a5e99..14462d6a34 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -75,8 +75,6 @@ private: int _invLookFlag; int _oldLook; bool _keyboardInput; - int _invMode; - int _invIndex; bool _pause; int _cNum; int _selector, _oldSelector; @@ -97,8 +95,6 @@ private: void toggleButton(int num); - void buttonPrint(const Common::Point &pt, int color, bool slamIt, const Common::String &str); - void examine(); void lookScreen(const Common::Point &pt); -- cgit v1.2.3 From 943d0a702fe468f14fb40f73ef68588705488037 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 30 Mar 2015 21:07:01 -0400 Subject: SHERLOCK: Beginnings of talk loading, added skeleton Scripts class --- engines/sherlock/inventory.cpp | 42 ++++-- engines/sherlock/inventory.h | 15 +- engines/sherlock/module.mk | 1 + engines/sherlock/people.h | 13 +- engines/sherlock/scene.cpp | 16 +- engines/sherlock/scene.h | 11 +- engines/sherlock/screen.cpp | 11 ++ engines/sherlock/screen.h | 4 + engines/sherlock/scripts.cpp | 35 +++++ engines/sherlock/scripts.h | 48 ++++++ engines/sherlock/sherlock.cpp | 14 +- engines/sherlock/sherlock.h | 6 +- engines/sherlock/talk.cpp | 291 +++++++++++++++++++++++++++++++++++- engines/sherlock/talk.h | 43 +++++- engines/sherlock/user_interface.cpp | 58 ++++--- engines/sherlock/user_interface.h | 11 +- 16 files changed, 542 insertions(+), 77 deletions(-) create mode 100644 engines/sherlock/scripts.cpp create mode 100644 engines/sherlock/scripts.h diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index a7691fc866..ac37e7c587 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -40,7 +40,7 @@ Inventory::Inventory(SherlockEngine *vm) : Common::Array(), _vm(v _holdings = 0; _oldFlag = 0; _invFlag = 0; - _invMode = 0; + _invMode = INVMODE_EXIT; } Inventory::~Inventory() { @@ -117,7 +117,7 @@ void Inventory::loadGraphics() { * and returns the numer that matches the passed name */ int Inventory::findInv(const Common::String &name) { - for (int idx = 0; idx < size(); ++idx) { + for (int idx = 0; idx < (int)size(); ++idx) { if (scumm_stricmp(name.c_str(), _names[idx].c_str()) == 0) return idx; } @@ -219,25 +219,25 @@ void Inventory::drawInventory(int flag) { // Draw the buttons screen.makeButton(Common::Rect(INVENTORY_POINTS[0][0], CONTROLS_Y1, INVENTORY_POINTS[0][1], - CONTROLS_Y1 + 9), INVENTORY_POINTS[0][2] - screen.stringWidth("Exit") / 2, "Exit"); + CONTROLS_Y1 + 10), INVENTORY_POINTS[0][2] - screen.stringWidth("Exit") / 2, "Exit"); screen.makeButton(Common::Rect(INVENTORY_POINTS[1][0], CONTROLS_Y1, INVENTORY_POINTS[1][1], - CONTROLS_Y1 + 9), INVENTORY_POINTS[1][2] - screen.stringWidth("Look") / 2, "Look"); + CONTROLS_Y1 + 10), INVENTORY_POINTS[1][2] - screen.stringWidth("Look") / 2, "Look"); screen.makeButton(Common::Rect(INVENTORY_POINTS[2][0], CONTROLS_Y1, INVENTORY_POINTS[2][1], - CONTROLS_Y1 + 9), INVENTORY_POINTS[2][2] - screen.stringWidth("Use") / 2, "Use"); + CONTROLS_Y1 + 10), INVENTORY_POINTS[2][2] - screen.stringWidth("Use") / 2, "Use"); screen.makeButton(Common::Rect(INVENTORY_POINTS[3][0], CONTROLS_Y1, INVENTORY_POINTS[3][1], - CONTROLS_Y1 + 9), INVENTORY_POINTS[3][2] - screen.stringWidth("Give") / 2, "Give"); + CONTROLS_Y1 + 10), INVENTORY_POINTS[3][2] - screen.stringWidth("Give") / 2, "Give"); screen.makeButton(Common::Rect(INVENTORY_POINTS[4][0], CONTROLS_Y1, INVENTORY_POINTS[4][1], - CONTROLS_Y1 + 9), INVENTORY_POINTS[4][2], "^^"); + CONTROLS_Y1 + 10), INVENTORY_POINTS[4][2], "^^"); screen.makeButton(Common::Rect(INVENTORY_POINTS[5][0], CONTROLS_Y1, INVENTORY_POINTS[5][1], - CONTROLS_Y1 + 9), INVENTORY_POINTS[5][2], "^"); + CONTROLS_Y1 + 10), INVENTORY_POINTS[5][2], "^"); screen.makeButton(Common::Rect(INVENTORY_POINTS[6][0], CONTROLS_Y1, INVENTORY_POINTS[6][1], - CONTROLS_Y1 + 9), INVENTORY_POINTS[6][2], "_"); + CONTROLS_Y1 + 10), INVENTORY_POINTS[6][2], "_"); screen.makeButton(Common::Rect(INVENTORY_POINTS[7][0], CONTROLS_Y1, INVENTORY_POINTS[7][1], - CONTROLS_Y1 + 9), INVENTORY_POINTS[7][2], "__"); + CONTROLS_Y1 + 10), INVENTORY_POINTS[7][2], "__"); if (tempFlag == 128) flag = 1; - _invMode = flag; + _invMode = (InvMode)flag; if (flag) { ui._oldKey = INVENTORY_COMMANDS[flag]; @@ -334,7 +334,25 @@ void Inventory::doInvLite(int index, byte color) { } void Inventory::doInvJF() { - // TODO + Screen &screen = *_vm->_screen; + Talk &talk = *_vm->_talk; + UserInterface &ui = *_vm->_ui; + + ui._invLookFlag = true; + freeInv(); + + ui._infoFlag = true; + ui.clearInfo(); + + screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(0, CONTROLS_Y), + Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + ui.examine(); + + if (!talk._talkToAbort) { + screen._backBuffer2.blitFrom((*ui._controlPanel)[0]._frame, + Common::Point(0, CONTROLS_Y)); + loadInv(); + } } } // End of namespace Sherlock diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index e9a4ba5548..3c01dc38da 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -32,6 +32,19 @@ namespace Sherlock { #define MAX_VISIBLE_INVENTORY 6 +enum InvMode { + INVMODE_EXIT = 0, + INVMODE_LOOK = 1, + INVMODE_USE = 2, + INVMODE_GIVE = 3, + INVMODE_FIRST = 4, + INVMODE_PREVIOUS = 5, + INVMODE_NEXT = 6, + INVMODE_LAST = 7, + INVMODE_INVALID = 8, + INVMODE_USE55 = 255 +}; + struct InventoryItem { int _requiredFlag; Common::String _name; @@ -50,7 +63,7 @@ public: ImageFile *_invShapes[MAX_VISIBLE_INVENTORY]; Common::StringArray _names; bool _invGraphicsLoaded; - int _invMode; + InvMode _invMode; int _invIndex; int _holdings; void freeGraphics(); diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk index 4101769a80..a01f9f0f71 100644 --- a/engines/sherlock/module.mk +++ b/engines/sherlock/module.mk @@ -18,6 +18,7 @@ MODULE_OBJS = \ resources.o \ scene.o \ screen.o \ + scripts.o \ sherlock.o \ sound.o \ talk.o \ diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index 0393528095..6b5c59b1bd 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -52,17 +52,24 @@ enum { class SherlockEngine; +class Person: public Sprite { +public: + Person() : Sprite() {} + + Common::String _portrait; +}; + class People { private: SherlockEngine *_vm; - Sprite _data[MAX_PEOPLE]; - Sprite &_player; + Person _data[MAX_PEOPLE]; bool _walkLoaded; int _oldWalkSequence; int _srcZone, _destZone; public: Common::Point _walkDest; Common::Stack _walkTo; + Person &_player; bool _holmesOn; bool _portraitLoaded; Object _portrait; @@ -72,7 +79,7 @@ public: People(SherlockEngine *vm); ~People(); - Sprite &operator[](PeopleId id) { return _data[id]; } + Person &operator[](PeopleId id) { return _data[id]; } bool isHolmesActive() const { return _walkLoaded && _holmesOn; } diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index c3afc4a0d4..7c66a1dc62 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -99,7 +99,6 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { _hsavedPos = Common::Point(-1, -1); _hsavedFs = -1; _cAnimFramePause = 0; - _invMode = INVMODE_0; _restoreFlag = false; _invLookFlag = false; _lookHelp = false; @@ -119,6 +118,7 @@ void Scene::selectScene() { Events &events = *_vm->_events; People &people = *_vm->_people; Screen &screen = *_vm->_screen; + Scripts &scripts = *_vm->_scripts; UserInterface &ui = *_vm->_ui; // Reset fields @@ -150,8 +150,8 @@ void Scene::selectScene() { // If there were any scripst waiting to be run, but were interrupt by a running // canimation (probably the last scene's exit canim), clear the _scriptMoreFlag - if (_vm->_scriptMoreFlag == 3) - _vm->_scriptMoreFlag = 0; + if (scripts._scriptMoreFlag == 3) + scripts._scriptMoreFlag = 0; } /** @@ -1050,8 +1050,10 @@ int Scene::startCAnim(int cAnimNum, int playRate) { */ void Scene::doBgAnim() { Events &events = *_vm->_events; + Inventory &inv = *_vm->_inventory; People &people = *_vm->_people; Screen &screen = *_vm->_screen; + Scripts &scripts = *_vm->_scripts; Sound &sound = *_vm->_sound; Talk &talk = *_vm->_talk; UserInterface &ui = *_vm->_ui; @@ -1079,7 +1081,7 @@ void Scene::doBgAnim() { // Check for setting magnifying glass cursor if (ui._menuMode == INV_MODE || ui._menuMode == USE_MODE || ui._menuMode == GIVE_MODE) { - if (_invMode == INVMODE_1) { + if (inv._invMode == INVMODE_LOOK) { // Only show Magnifying glass cursor if it's not on the inventory command line if (mousePos.y < CONTROLS_Y || mousePos.y >(CONTROLS_Y1 + 13)) events.setCursor(MAGNIFY); @@ -1357,10 +1359,10 @@ void Scene::doBgAnim() { // Check if the method was called for calling a portrait, and a talk was // interrupting it. This talk file would not have been executed at the time, // since we needed to finish the 'doBgAnim' to finish clearing the portrait - if (people._clearingThePortrait && _vm->_scriptMoreFlag == 3) { + if (people._clearingThePortrait && scripts._scriptMoreFlag == 3) { // Reset the flags and call to talk - people._clearingThePortrait = _vm->_scriptMoreFlag = 0; - talk.talkTo(_vm->_scriptName); + people._clearingThePortrait = scripts._scriptMoreFlag = 0; + talk.talkTo(scripts._scriptName); } } diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index d89a47e560..cd64073621 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -35,14 +35,6 @@ namespace Sherlock { #define MAX_ZONES 40 #define INFO_LINE 140 -enum InvMode { - INVMODE_0 = 0, - INVMODE_1 = 1, - INVMODE_2 = 2, - INVMODE_3 = 3, - INVMODE_255 = 255 -}; - class SherlockEngine; struct BgFileHeader { @@ -94,9 +86,7 @@ class Scene { private: SherlockEngine *_vm; Common::String _rrmName; - InvMode _invMode; int _selector; - bool _invLookFlag; bool _lookHelp; bool loadScene(const Common::String &filename); @@ -149,6 +139,7 @@ public: bool _doBgAnimDone; int _tempFadeStyle; int _cAnimFramePause; + bool _invLookFlag; public: Scene(SherlockEngine *vm); ~Scene(); diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index a3705b54da..0eeddf2a5f 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -468,4 +468,15 @@ void Screen::makePanel(const Common::Rect &r) { _backBuffer->hLine(r.left + 1, r.bottom - 2, r.right - 1, BUTTON_BOTTOM); } +void Screen::setDisplayBounds(const Common::Rect &r) { + // TODO: See if needed +} +void Screen::resetDisplayBounds() { + setDisplayBounds(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); +} + +Common::Rect Screen::getDisplayBounds() { + return Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); +} + } // End of namespace Sherlock diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 5047d40216..597c47c83a 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -120,6 +120,10 @@ public: void buttonPrint(const Common::Point &pt, byte color, bool slamIt, const Common::String &str); void makePanel(const Common::Rect &r); + + void setDisplayBounds(const Common::Rect &r); + void resetDisplayBounds(); + Common::Rect getDisplayBounds(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/scripts.cpp b/engines/sherlock/scripts.cpp new file mode 100644 index 0000000000..ace957bd76 --- /dev/null +++ b/engines/sherlock/scripts.cpp @@ -0,0 +1,35 @@ +/* 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 "sherlock/scripts.h" +#include "sherlock/sherlock.h" + +namespace Sherlock { + +Scripts::Scripts(SherlockEngine *vm): _vm(vm) { + _scriptMoreFlag = 0; + _scriptSaveIndex = 0; + _scriptSelect = 0; + _abortFlag = false; +} + +} // End of namespace Sherlock diff --git a/engines/sherlock/scripts.h b/engines/sherlock/scripts.h new file mode 100644 index 0000000000..eede1ca103 --- /dev/null +++ b/engines/sherlock/scripts.h @@ -0,0 +1,48 @@ +/* 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 SHERLOCK_SCRIPTS_H +#define SHERLOCK_SCRIPTS_H + +#include "common/scummsys.h" +#include "common/array.h" + +namespace Sherlock { + +class SherlockEngine; + +class Scripts { +private: + SherlockEngine *_vm; +public: + int _scriptMoreFlag; + Common::String _scriptName; + int _scriptSaveIndex; + int _scriptSelect; + bool _abortFlag; +public: + Scripts(SherlockEngine *vm); +}; + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 107dee5a41..04a9ed54d5 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -39,6 +39,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _res = nullptr; _scene = nullptr; _screen = nullptr; + _scripts = nullptr; _sound = nullptr; _talk = nullptr; _ui = nullptr; @@ -47,7 +48,6 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _loadingSavedGame = false; _onChessboard = false; _slowChess = false; - _scriptMoreFlag = 0; } SherlockEngine::~SherlockEngine() { @@ -58,6 +58,7 @@ SherlockEngine::~SherlockEngine() { delete _people; delete _scene; delete _screen; + delete _scripts; delete _sound; delete _talk; delete _ui; @@ -82,6 +83,7 @@ void SherlockEngine::initialize() { _people = new People(this); _scene = new Scene(this); _screen = new Screen(this); + _scripts = new Scripts(this); _sound = new Sound(this); _talk = new Talk(this); _ui = new UserInterface(this); @@ -120,10 +122,10 @@ void SherlockEngine::sceneLoop() { while (!shouldQuit() && _scene->_goToScene == -1) { // See if a script needs to be completed from either a goto room code, // or a script that was interrupted by another script - if (_scriptMoreFlag == 1 || _scriptMoreFlag == 3) - _talk->talkTo(_scriptName); + if (_scripts->_scriptMoreFlag == 1 || _scripts->_scriptMoreFlag == 3) + _talk->talkTo(_scripts->_scriptName); else - _scriptMoreFlag = 0; + _scripts->_scriptMoreFlag = 0; // Handle any input from the keyboard or mouse handleInput(); @@ -171,4 +173,8 @@ void SherlockEngine::setFlags(int flagNum) { _scene->checkSceneFlags(true); } +void SherlockEngine::freeSaveGameList() { + // TODO +} + } // End of namespace Comet diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 392f55839e..7b562e0a23 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -40,6 +40,7 @@ #include "sherlock/resources.h" #include "sherlock/scene.h" #include "sherlock/screen.h" +#include "sherlock/scripts.h" #include "sherlock/sound.h" #include "sherlock/talk.h" #include "sherlock/user_interface.h" @@ -89,6 +90,7 @@ public: Resources *_res; Scene *_scene; Screen *_screen; + Scripts *_scripts; Sound *_sound; Talk *_talk; UserInterface *_ui; @@ -104,8 +106,6 @@ public: Common::Array _map; // Map locations for each scene bool _onChessboard; bool _slowChess; - int _scriptMoreFlag; - Common::String _scriptName; public: SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc); virtual ~SherlockEngine(); @@ -125,6 +125,8 @@ public: bool readFlags(int flagNum); void setFlags(int flagNum); + + void freeSaveGameList(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index ff71d37a2f..d67013b60e 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -25,13 +25,238 @@ namespace Sherlock { +/** + * Load the data for a single statement within a talk file + */ +void Statement::synchronize(Common::SeekableReadStream &s, bool voices) { + int length; + + length = s.readUint16LE(); + for (int idx = 0; idx < length; ++idx) + _statement += (char)s.readByte(); + + length = s.readUint16LE(); + for (int idx = 0; idx < length; ++idx) + _reply += (char)s.readByte(); + + // If we don't have digital sound, we'll need to strip out voice commands from reply + if (!voices) { + // Scan for a 140 byte, which indicates playing a sound + for (uint idx = 0; idx < _reply.size(); ++idx) { + if (_reply[idx] == 140) { + // Replace instruction character with a space, and delete the + // rest of the name following it + _reply = Common::String(_reply.c_str(), _reply.c_str() + idx) + " " + + Common::String(_reply.c_str() + 9); + } + } + + // Ensure the last character of the reply is not a space from the prior + // conversion loop, to avoid any issues with the space ever causing a page + // wrap, and ending up displaying another empty page + while (_reply.lastChar() == ' ') + _reply.deleteLastChar(); + } + + length = s.readUint16LE(); + for (int idx = 0; idx < length; ++idx) + _linkFile += (char)s.readByte(); + + length = s.readUint16LE(); + for (int idx = 0; idx < length; ++idx) + _voiceFile += (char)s.readByte(); + + _required.resize(s.readByte()); + _modified.resize(s.readByte()); + + // Read in flag required/modified data + for (uint idx = 0; idx < _required.size(); ++idx) + _required[idx] = s.readUint16LE(); + for (uint idx = 0; idx < _modified.size(); ++idx) + _modified[idx] = s.readUint16LE(); + + _portraitSide = s.readByte(); + _quotient = s.readUint16LE(); +} + +/*----------------------------------------------------------------*/ + Talk::Talk(SherlockEngine *vm): _vm(vm) { _talkCounter = 0; _talkToAbort = false; + _saveSeqNum = 0; + _speaker = 0; + _talkIndex = 0; + _talkTo = 0; } -void Talk::talkTo(const Common::String &name) { - // TODO +/** + * Called when either an NPC initiates a conversation or for inventory item + * descriptions. It opens up a description window similar to how 'talk' does, + * but shows a 'reply' directly instead of waiting for a statement option. + */ +void Talk::talkTo(const Common::String &filename) { + Events &events = *_vm->_events; + Inventory &inv = *_vm->_inventory; + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + Screen &screen = *_vm->_screen; + Scripts &scripts = *_vm->_scripts; + Talk &talk = *_vm->_talk; + UserInterface &ui = *_vm->_ui; + Common::Rect savedBounds = screen.getDisplayBounds(); + + if (filename.empty()) + // No filename passed, so exit + return; + + // If there any canimations currently running, or a portrait is being cleared, + // save the filename for later executing when the canimation is done + if (scene._ongoingCans || people._clearingThePortrait) { + // Make sure we're not in the middle of a script + if (!scripts._scriptMoreFlag) { + scripts._scriptName = filename; + scripts._scriptSaveIndex = 0; + + // Flag the selection, since we don't yet know which statement yet + scripts._scriptSelect = 100; + scripts._scriptMoreFlag = 3; + } + + return; + } + + // Save the ui mode temporarily and switch to talk mode + int savedMode = ui._menuMode; + ui._menuMode = TALK_MODE; + + // Turn on the Exit option + ui._endKeyActive = true; + + if (people[AL]._walkCount || people._walkTo.size() > 0) { + // Only interrupt if an action if trying to do an action, and not just + // if the player is walking around the scene + if (people._allowWalkAbort) + scripts._abortFlag = true; + + people.gotoStand(people._player); + } + + if (talk._talkToAbort) + return; + + talk.freeTalkVars(); + + // If any sequences have changed in the prior talk file, restore them + if (_savedSequences.size() > 0) { + for (uint idx = 0; idx < _savedSequences.size(); ++idx) { + SavedSequence &ss = _savedSequences[idx]; + for (uint idx2 = 0; idx2 < _savedSequences.size(); ++idx2) + scene._bgShapes[ss._objNum]._sequences[idx2] = ss._sequences[idx2]; + + // Reset the object's frame to the beginning of the sequence + scene._bgShapes[ss._objNum]._frameNumber = 0; + } + } + + while (_sequenceStack.empty()) + pullSequence(); + + // Restore any pressed button + if (!ui._windowOpen && savedMode != STD_MODE) + ui.restoreButton(savedMode - 1); + + // Clear the ui counter so that anything displayed on the info line + // before the window was opened isn't cleared + ui._menuCounter = 0; + + // Close any previous window before starting the talk + if (ui._windowOpen) { + switch (savedMode) { + case LOOK_MODE: + events.setCursor(ARROW); + + if (ui._invLookFlag) { + screen.resetDisplayBounds(); + ui.drawInterface(2); + } + + ui.banishWindow(); + ui._windowBounds.top = CONTROLS_Y1; + ui._temp = ui._oldTemp = ui._lookHelp = 0; + ui._menuMode = STD_MODE; + events._pressed = events._released = events._oldButtons = 0; + ui._invLookFlag = false; + break; + + case TALK_MODE: + if (_speaker < 128) + clearTalking(); + if (_talkCounter) + return; + + // If we were in inventory mode looking at an object, restore the + // back buffers before closing the window, so we get the ui restored + // rather than the inventory again + if (ui._invLookFlag) { + screen.resetDisplayBounds(); + ui.drawInterface(2); + ui._invLookFlag = ui._lookScriptFlag = false; + } + + ui.banishWindow(); + ui._windowBounds.top = CONTROLS_Y1; + scripts._abortFlag = true; + break; + + case INV_MODE: + case USE_MODE: + case GIVE_MODE: + inv.freeInv(); + if (ui._invLookFlag) { + screen.resetDisplayBounds(); + ui.drawInterface(2); + ui._invLookFlag = ui._lookScriptFlag = false; + } + + ui._infoFlag = true; + ui.clearInfo(); + ui.banishWindow(false); + ui._key = -1; + break; + + case FILES_MODE: + ui.banishWindow(true); + ui._windowBounds.top = CONTROLS_Y1; + scripts._abortFlag = true; + break; + + case SETUP_MODE: + ui.banishWindow(true); + ui._windowBounds.top = CONTROLS_Y1; + ui._temp = ui._oldTemp = ui._lookHelp = ui._invLookFlag = false; + ui._menuMode = STD_MODE; + events._pressed = events._released = events._oldButtons = 0; + scripts._abortFlag = true; + break; + } + } + + screen.resetDisplayBounds(); + events._pressed = events._released = false; + loadTalkFile(filename); + ui._selector = ui._oldSelector = ui._key = ui._oldKey = -1; + + // Find the first statement that has the correct flags + int select = -1; + for (uint idx = 0; idx < _statements.size() && select == -1; ++idx) { + /* + if (!_talkMap[idx]) + select = _talkIndex = idx; + */ + } + + // TODOa } void Talk::talk(int objNum) { @@ -45,5 +270,67 @@ void Talk::freeTalkVars() { _statements.clear(); } +void Talk::pullSequence() { + // TODO +} + +/** + * Opens the talk file 'talk.tlk' and searches the index for the specified + * conversation. If found, the data for that conversation is loaded + */ +void Talk::loadTalkFile(const Common::String &filename) { + People &people = *_vm->_people; + Resources &res = *_vm->_res; + Sound &sound = *_vm->_sound; + + // Check for an existing person being talked to + _talkTo = -1; + for (int idx = 0; idx < MAX_PEOPLE; ++idx) { + if (scumm_strnicmp(filename.c_str(), people[(PeopleId)idx]._portrait.c_str(), 4)) { + _talkTo = idx; + break; + } + } + + const char *chP = strchr(filename.c_str(), '.'); + Common::String talkFile = !chP ? filename + ".tlk" : + Common::String(filename.c_str(), chP) + ".tlk"; + + // Open the talk file for reading + Common::SeekableReadStream *talkStream = res.load(talkFile); + talkStream->skip(2); // Skip talk file version num + + _statements.resize(talkStream->readByte()); + for (uint idx = 0; idx < _statements.size(); ++idx) + _statements[idx].synchronize(*talkStream, sound._voicesOn); + + delete talkStream; + setTalkMap(); +} + +void Talk::clearTalking() { + // TODO +} + +/** + * Form a translate table from the loaded statements from a talk file + */ +void Talk::setTalkMap() { + int statementNum = 0; + + for (uint sIdx = 0; sIdx < _statements.size(); ++sIdx) { + Statement &statement = _statements[sIdx]; + + // Set up talk map entry for the statement + bool valid = true; + for (uint idx = 0; idx < statement._required.size(); ++idx) { + if (!_vm->readFlags(statement._required[idx])) + valid = false; + } + + statement._talkMap = valid ? statementNum++ : -1; + } +} + } // End of namespace Sherlock diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index 9359b77e87..6ef4a04b6a 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -25,31 +25,58 @@ #include "common/scummsys.h" #include "common/array.h" +#include "common/stream.h" +#include "common/stack.h" namespace Sherlock { -struct TalkHistoryEntry { -private: - int _data[2]; -public: - TalkHistoryEntry() { _data[0] = _data[1] = 0; } +struct SavedSequence { + int _objNum; + Common::Array _sequences; +}; - int &operator[](int idx) { return _data[idx]; } +struct Statement { + Common::String _statement; + Common::String _reply; + Common::String _linkFile; + Common::String _voiceFile; + Common::Array _required; + Common::Array _modified; + int _portraitSide; + int _quotient; + int _talkMap; + + void synchronize(Common::SeekableReadStream &s, bool voices); }; class SherlockEngine; class Talk { + private: SherlockEngine *_vm; + int _saveSeqNum; + Common::Array _savedSequences; + Common::Stack _sequenceStack; + Common::Array _statements; + int _speaker; + int _talkIndex; + int _talkTo; + + void pullSequence(); + + void loadTalkFile(const Common::String &filename); + + void clearTalking(); + + void setTalkMap(); public: - Common::Array _statements; bool _talkToAbort; int _talkCounter; public: Talk(SherlockEngine *vm); - void talkTo(const Common::String &name); + void talkTo(const Common::String &filename); void talk(int objNum); diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 5e8b3287f0..9fe8a0979f 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -43,14 +43,14 @@ const int MENU_POINTS[12][4] = { // Inventory control locations */ const int INVENTORY_POINTS[8][3] = { - { 4, 50, 28 }, - { 52, 99, 76 }, - { 101, 140, 122 }, - { 142, 187, 165 }, - { 189, 219, 197 }, - { 221, 251, 233 }, - { 253, 283, 265 }, - { 285, 315, 293 } + { 4, 50, 29 }, + { 52, 99, 77 }, + { 101, 140, 123 }, + { 142, 187, 166 }, + { 189, 219, 198 }, + { 221, 251, 234 }, + { 253, 283, 266 }, + { 285, 315, 294 } }; const char COMMANDS[13] = "LMTPOCIUGJFS"; @@ -85,6 +85,7 @@ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { _windowStyle = 1; // Sliding windows _find = 0; _oldUse = 0; + _endKeyActive = true; } UserInterface::~UserInterface() { @@ -101,12 +102,15 @@ void UserInterface::reset() { /** * Draw the user interface onto the screen's back buffers */ -void UserInterface::drawInterface() { +void UserInterface::drawInterface(int bufferNum) { Screen &screen = *_vm->_screen; - screen._backBuffer2.fillRect(0, INFO_LINE, SHERLOCK_SCREEN_WIDTH, INFO_LINE + 10, INFO_BLACK); - screen._backBuffer1.transBlitFrom((*_controlPanel)[0], Common::Point(0, CONTROLS_Y)); - screen._backBuffer2.transBlitFrom((*_controlPanel)[0], Common::Point(0, CONTROLS_Y)); + if (bufferNum & 1) + screen._backBuffer1.transBlitFrom((*_controlPanel)[0], Common::Point(0, CONTROLS_Y)); + if (bufferNum & 2) + screen._backBuffer2.transBlitFrom((*_controlPanel)[0], Common::Point(0, CONTROLS_Y)); + if (bufferNum == 3) + screen._backBuffer2.fillRect(0, INFO_LINE, SHERLOCK_SCREEN_WIDTH, INFO_LINE + 10, INFO_BLACK); } /** @@ -118,6 +122,7 @@ void UserInterface::handleInput() { People &people = *_vm->_people; Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; + Scripts &scripts = *_vm->_scripts; Talk &talk = *_vm->_talk; if (_menuCounter) @@ -143,7 +148,7 @@ void UserInterface::handleInput() { } // Do button highlighting check - if (!_vm->_scriptMoreFlag) { // Don't if scripts are running + if (!scripts._scriptMoreFlag) { // Don't if scripts are running if (((events._rightPressed || events._rightReleased) && _helpStyle) || (!_helpStyle && !_menuCounter)) { // Handle any default commands if we're in STD_MODE @@ -276,7 +281,7 @@ void UserInterface::handleInput() { case GIVE_MODE: case INV_MODE: if (inv._invMode == 1 || inv._invMode == 2 || inv._invMode == 3) { - if (pt.y < CONTROLS_Y) + if (pt.y > CONTROLS_Y) lookInv(); else lookScreen(pt); @@ -713,7 +718,7 @@ void UserInterface::doInvControl() { screen.buttonPrint(Common::Point(INVENTORY_POINTS[1][2], CONTROLS_Y1), colors[1], true, "Look"); screen.buttonPrint(Common::Point(INVENTORY_POINTS[2][2], CONTROLS_Y1), colors[1], true, "Use"); screen.buttonPrint(Common::Point(INVENTORY_POINTS[3][2], CONTROLS_Y1), colors[1], true, "Give"); - inv._invMode = found; + inv._invMode = (InvMode)found; _selector = -1; } @@ -734,7 +739,11 @@ void UserInterface::doInvControl() { bool flag = false; if (inv._invMode == 1 || inv._invMode == 2 || inv._invMode == 3) { Common::Rect r(15, CONTROLS_Y1 + 11, 314, SHERLOCK_SCREEN_HEIGHT - 2); - flag = (_selector < inv._holdings); + if (r.contains(mousePos)) { + _selector = (mousePos.x - 6) / 52 + inv._invIndex; + if (_selector < inv._holdings) + flag = true; + } } if (!flag && mousePos.y >(CONTROLS_Y1 + 11)) @@ -753,13 +762,13 @@ void UserInterface::doInvControl() { int temp = inv._invMode; const char *chP = strchr(INVENTORY_COMMANDS, _key); - inv._invMode = !chP ? 8 : chP - INVENTORY_COMMANDS; + inv._invMode = !chP ? INVMODE_INVALID : (InvMode)(chP - INVENTORY_COMMANDS); inv.invCommands(true); - inv._invMode = temp; + inv._invMode = (InvMode)temp; _keyboardInput = true; if (_key == 'E') - inv._invMode = STD_MODE; + inv._invMode = INVMODE_EXIT; _selector = -1; } else { _selector = -1; @@ -789,11 +798,11 @@ void UserInterface::doInvControl() { events.clearEvents(); events.setCursor(ARROW); } else if ((found == 1 && events._released) || (_key == 'L')) { - inv._invMode = 1; + inv._invMode = INVMODE_LOOK; } else if ((found == 2 && events._released) || (_key == 'U')) { - inv._invMode = 2; + inv._invMode = INVMODE_USE; } else if ((found == 3 && events._released) || (_key == 'G')) { - inv._invMode = 3; + inv._invMode = INVMODE_GIVE; } else if (((found == 4 && events._released) || _key == ',') && inv._invIndex) { if (inv._invIndex >= 6) inv._invIndex -= 6; @@ -855,7 +864,8 @@ void UserInterface::doInvControl() { // If it's -1, then no inventory item is highlighted yet. Otherwise, // an object in the scene has been clicked. - if (_selector != -1 && inv._invMode == 1 && mousePos.y >(CONTROLS_Y1 + 11)) + if (_selector != -1 && inv._invMode == INVMODE_LOOK + && mousePos.y >(CONTROLS_Y1 + 11)) inv.doInvJF(); if (talk._talkToAbort) @@ -879,7 +889,7 @@ void UserInterface::doInvControl() { inv.putInv(1); _selector = temp; // Restore it temp = inv._invMode; - inv._invMode = -1; + inv._invMode = INVMODE_USE55; inv.invCommands(true); _infoFlag = true; diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index 14462d6a34..157900f0aa 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -57,9 +57,11 @@ extern const char INVENTORY_COMMANDS[9]; class SherlockEngine; class Inventory; +class Talk; class UserInterface { friend class Inventory; + friend class Talk; private: SherlockEngine *_vm; ImageFile *_controlPanel; @@ -72,7 +74,6 @@ private: int _help, _oldHelp; int _key, _oldKey; int _temp, _oldTemp; - int _invLookFlag; int _oldLook; bool _keyboardInput; bool _pause; @@ -89,8 +90,6 @@ private: private: void depressButton(int num); - void restoreButton(int num); - void pushButton(int num); void toggleButton(int num); @@ -120,13 +119,15 @@ public: int _menuCounter; bool _infoFlag; bool _windowOpen; + bool _endKeyActive; + int _invLookFlag; public: UserInterface(SherlockEngine *vm); ~UserInterface(); void reset(); - void drawInterface(); + void drawInterface(int bufferNum = 3); void handleInput(); @@ -140,6 +141,8 @@ public: void summonWindow(const Surface &bgSurface, bool slideUp = true); void summonWindow(bool slideUp = true, int height = CONTROLS_Y); void banishWindow(bool slideUp = true); + + void restoreButton(int num); }; } // End of namespace Sherlock -- cgit v1.2.3 From cf4226be45ddea933ef17722eac0f5ccadc7357b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 31 Mar 2015 07:55:54 -0400 Subject: SHERLOCK: Implemented talkTo --- engines/sherlock/journal.cpp | 4 + engines/sherlock/journal.h | 2 + engines/sherlock/scripts.cpp | 26 +++- engines/sherlock/scripts.h | 20 ++- engines/sherlock/talk.cpp | 241 +++++++++++++++++++++++++++++++----- engines/sherlock/talk.h | 19 ++- engines/sherlock/user_interface.cpp | 10 ++ engines/sherlock/user_interface.h | 2 + 8 files changed, 290 insertions(+), 34 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index ad7df48943..34423d2480 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -37,4 +37,8 @@ Journal::Journal() { _page = 0; } +void Journal::record(int converseNum, int statementNum) { + // TODO +} + } // End of namespace Sherlock diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h index 64158ff123..87e5a4f8f2 100644 --- a/engines/sherlock/journal.h +++ b/engines/sherlock/journal.h @@ -39,6 +39,8 @@ public: int _page; public: Journal(); + + void record(int converseNum, int statementNum); }; } // End of namespace Sherlock diff --git a/engines/sherlock/scripts.cpp b/engines/sherlock/scripts.cpp index ace957bd76..1da72c976b 100644 --- a/engines/sherlock/scripts.cpp +++ b/engines/sherlock/scripts.cpp @@ -29,7 +29,31 @@ Scripts::Scripts(SherlockEngine *vm): _vm(vm) { _scriptMoreFlag = 0; _scriptSaveIndex = 0; _scriptSelect = 0; - _abortFlag = false; } +void Scripts::doScript(const Common::String &str) { + // TODO +} + +void Scripts::pullSeq() { + // TODO +} + +void Scripts::pushSeq(int speak) { + // TODO +} + +void Scripts::setStillSeq(int speak) { + // TODO +} + +void Scripts::popStack() { + ScriptEntry script = _scriptStack.pop(); + _scriptName = script._name; + _scriptSaveIndex = script._index; + _scriptSelect = script._select; + _scriptMoreFlag = true; +} + + } // End of namespace Sherlock diff --git a/engines/sherlock/scripts.h b/engines/sherlock/scripts.h index eede1ca103..6c23e72fe4 100644 --- a/engines/sherlock/scripts.h +++ b/engines/sherlock/scripts.h @@ -24,23 +24,39 @@ #define SHERLOCK_SCRIPTS_H #include "common/scummsys.h" -#include "common/array.h" +#include "common/stack.h" namespace Sherlock { class SherlockEngine; +struct ScriptEntry { + Common::String _name; + int _index; + int _select; +}; + class Scripts { private: SherlockEngine *_vm; public: + Common::Stack _scriptStack; int _scriptMoreFlag; Common::String _scriptName; int _scriptSaveIndex; int _scriptSelect; - bool _abortFlag; public: Scripts(SherlockEngine *vm); + + void doScript(const Common::String &str); + + void pullSeq(); + + void pushSeq(int speak); + + void setStillSeq(int speak); + + void popStack(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index d67013b60e..e3c5ebc5e0 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -25,10 +25,14 @@ namespace Sherlock { +#define SFX_COMMAND 140 + +/*----------------------------------------------------------------*/ + /** * Load the data for a single statement within a talk file */ -void Statement::synchronize(Common::SeekableReadStream &s, bool voices) { +void Statement::synchronize(Common::SeekableReadStream &s) { int length; length = s.readUint16LE(); @@ -39,25 +43,6 @@ void Statement::synchronize(Common::SeekableReadStream &s, bool voices) { for (int idx = 0; idx < length; ++idx) _reply += (char)s.readByte(); - // If we don't have digital sound, we'll need to strip out voice commands from reply - if (!voices) { - // Scan for a 140 byte, which indicates playing a sound - for (uint idx = 0; idx < _reply.size(); ++idx) { - if (_reply[idx] == 140) { - // Replace instruction character with a space, and delete the - // rest of the name following it - _reply = Common::String(_reply.c_str(), _reply.c_str() + idx) + " " + - Common::String(_reply.c_str() + 9); - } - } - - // Ensure the last character of the reply is not a space from the prior - // conversion loop, to avoid any issues with the space ever causing a page - // wrap, and ending up displaying another empty page - while (_reply.lastChar() == ' ') - _reply.deleteLastChar(); - } - length = s.readUint16LE(); for (int idx = 0; idx < length; ++idx) _linkFile += (char)s.readByte(); @@ -81,6 +66,12 @@ void Statement::synchronize(Common::SeekableReadStream &s, bool voices) { /*----------------------------------------------------------------*/ +TalkHistoryEntry::TalkHistoryEntry() { + Common::fill(&_data[0], &_data[16], false); +} + +/*----------------------------------------------------------------*/ + Talk::Talk(SherlockEngine *vm): _vm(vm) { _talkCounter = 0; _talkToAbort = false; @@ -88,6 +79,10 @@ Talk::Talk(SherlockEngine *vm): _vm(vm) { _speaker = 0; _talkIndex = 0; _talkTo = 0; + _scriptSelect = 0; + _converseNum = -1; + _talkStealth = 0; + _talkToFlag = -1; } /** @@ -98,6 +93,7 @@ Talk::Talk(SherlockEngine *vm): _vm(vm) { void Talk::talkTo(const Common::String &filename) { Events &events = *_vm->_events; Inventory &inv = *_vm->_inventory; + Journal &journal = *_vm->_journal; People &people = *_vm->_people; Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; @@ -105,6 +101,7 @@ void Talk::talkTo(const Common::String &filename) { Talk &talk = *_vm->_talk; UserInterface &ui = *_vm->_ui; Common::Rect savedBounds = screen.getDisplayBounds(); + bool abortFlag = false; if (filename.empty()) // No filename passed, so exit @@ -137,7 +134,7 @@ void Talk::talkTo(const Common::String &filename) { // Only interrupt if an action if trying to do an action, and not just // if the player is walking around the scene if (people._allowWalkAbort) - scripts._abortFlag = true; + abortFlag = true; people.gotoStand(people._player); } @@ -206,7 +203,7 @@ void Talk::talkTo(const Common::String &filename) { ui.banishWindow(); ui._windowBounds.top = CONTROLS_Y1; - scripts._abortFlag = true; + abortFlag = true; break; case INV_MODE: @@ -228,7 +225,7 @@ void Talk::talkTo(const Common::String &filename) { case FILES_MODE: ui.banishWindow(true); ui._windowBounds.top = CONTROLS_Y1; - scripts._abortFlag = true; + abortFlag = true; break; case SETUP_MODE: @@ -237,7 +234,7 @@ void Talk::talkTo(const Common::String &filename) { ui._temp = ui._oldTemp = ui._lookHelp = ui._invLookFlag = false; ui._menuMode = STD_MODE; events._pressed = events._released = events._oldButtons = 0; - scripts._abortFlag = true; + abortFlag = true; break; } } @@ -250,13 +247,161 @@ void Talk::talkTo(const Common::String &filename) { // Find the first statement that has the correct flags int select = -1; for (uint idx = 0; idx < _statements.size() && select == -1; ++idx) { - /* - if (!_talkMap[idx]) + if (_statements[idx]._talkMap == 0) select = _talkIndex = idx; - */ } - // TODOa + if (scripts._scriptMoreFlag && _scriptSelect != 0) + select = _scriptSelect; + + if (select == -1) + error("Couldn't find statement to display"); + + // Add the statement into the journal and talk history + if (_talkTo != -1 && !_talkHistory[_converseNum][select]) + journal.record(_converseNum | 2048, select); + _talkHistory[_converseNum][select] = true; + + // Check if the talk file is meant to be a non-seen comment + if (filename[7] != '*') { + // Should we start in stealth mode? + if (_statements[select]._statement.hasPrefix("^")) { + _talkStealth = 2; + } else { + // Not in stealth mode, so bring up the ui window + _talkStealth = 0; + ++_talkToFlag; + events.setCursor(WAIT); + + ui._windowBounds.top = CONTROLS_Y; + ui._infoFlag = true; + ui.clearInfo(); + } + + // Handle replies until there's no further linked file, + // or the link file isn't a reply first cnversation + for (;;) { + _sequenceStack.clear(); + _scriptSelect = select; + _speaker = _talkTo; + + Statement &statement = _statements[select]; + scripts.doScript(_statements[select]._reply); + + if (_talkToAbort) + return; + + if (!_talkStealth) + ui.clearWindow(); + + if (statement._modified.size() > 0) { + for (uint idx = 0; idx < statement._modified.size(); ++idx) + _vm->setFlags(statement._modified[idx]); + + setTalkMap(); + } + + // Check for a linked file + if (!statement._linkFile.empty() && !scripts._scriptMoreFlag) { + freeTalkVars(); + loadTalkFile(statement._linkFile); + + // Scan for the first valid statement in the newly loaded file + select = -1; + for (uint idx = 0; idx < _statements.size(); ++idx) { + if (_statements[idx]._talkMap == 0) { + select = idx; + break; + } + } + + if (_talkToFlag == 1) + scripts.pullSeq(); + + // Set the stealth mode for the new talk file + Statement &newStatement = _statements[select]; + _talkStealth = newStatement._statement.hasPrefix("^") ? 2 : 0; + + // If the new conversion is a reply first, then we don't need + // to display any choices, since the reply needs to be shown + if (!newStatement._statement.hasPrefix("*") && + !newStatement._statement.hasPrefix("^")) { + _sequenceStack.clear(); + scripts.pushSeq(_talkTo); + scripts.setStillSeq(_talkTo); + _talkIndex = select; + ui._selector = ui._oldSelector = -1; + + if (!ui._windowOpen) { + // Draw the talk interface on the back buffer + drawInterface(); + displayTalk(false); + } else { + displayTalk(true); + } + + byte color = ui._endKeyActive ? COMMAND_FOREGROUND : COMMAND_NULL; + + // If the window is alraedy open, simply draw. Otherwise, do it + // to the back buffer and then summon the window + if (ui._windowOpen) { + screen.buttonPrint(Common::Point(119, CONTROLS_Y), color, true, "Exit"); + } else { + screen.buttonPrint(Common::Point(119, CONTROLS_Y), color, false, "Exit"); + + if (!ui._windowStyle) { + screen.slamRect(Common::Rect(0, CONTROLS_Y, + SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + } else { + ui.summonWindow(); + } + + ui._windowOpen = true; + } + + // Break out of loop now that we're waiting for player input + events.setCursor(ARROW); + break; + } else { + // Add the statement into the journal and talk history + if (_talkTo != -1 && !_talkHistory[_converseNum][select]) + journal.record(_converseNum | 2048, select); + _talkHistory[_converseNum][select] = true; + + } + + ui._key = ui._oldKey = COMMANDS[TALK_MODE - 1]; + ui._temp = ui._oldTemp = 0; + ui._menuMode = TALK_MODE; + _talkToFlag = 2; + } else { + freeTalkVars(); + + if (!ui._lookScriptFlag) { + ui.banishWindow(); + ui._windowBounds.top = CONTROLS_Y1; + ui._menuMode = STD_MODE; + } + + break; + } + } + } + + _talkStealth = 0; + events._pressed = events._released = events._oldButtons = 0; + events.clearKeyboard(); + + screen.setDisplayBounds(savedBounds); + _talkToAbort = abortFlag; + + // If a script was added to the script stack, restore state so that the + // previous script can continue + if (!scripts._scriptStack.empty()) { + scripts.popStack(); + } + + events.setCursor(ARROW); } void Talk::talk(int objNum) { @@ -302,9 +447,12 @@ void Talk::loadTalkFile(const Common::String &filename) { _statements.resize(talkStream->readByte()); for (uint idx = 0; idx < _statements.size(); ++idx) - _statements[idx].synchronize(*talkStream, sound._voicesOn); + _statements[idx].synchronize(*talkStream); delete talkStream; + + if (!sound._voicesOn) + stripVoiceCommands(); setTalkMap(); } @@ -313,7 +461,33 @@ void Talk::clearTalking() { } /** - * Form a translate table from the loaded statements from a talk file + * Remove any voice commands from a loaded statement list + */ +void Talk::stripVoiceCommands() { + for (uint sIdx = 0; sIdx < _statements.size(); ++sIdx) { + Statement &statement = _statements[sIdx]; + + // Scan for an sound effect byte, which indicates to play a sound + for (uint idx = 0; idx < statement._reply.size(); ++idx) { + if (statement._reply[idx] == SFX_COMMAND) { + // Replace instruction character with a space, and delete the + // rest of the name following it + statement._reply = Common::String(statement._reply.c_str(), + statement._reply.c_str() + idx) + " " + + Common::String(statement._reply.c_str() + 9); + } + } + + // Ensure the last character of the reply is not a space from the prior + // conversion loop, to avoid any issues with the space ever causing a page + // wrap, and ending up displaying another empty page + while (statement._reply.lastChar() == ' ') + statement._reply.deleteLastChar(); + } +} + +/** + * Form a table of the display indexes for statements */ void Talk::setTalkMap() { int statementNum = 0; @@ -332,5 +506,12 @@ void Talk::setTalkMap() { } } +void Talk::drawInterface() { + // TODO +} + +void Talk::displayTalk(bool slamIt) { + // TODO +} } // End of namespace Sherlock diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index 6ef4a04b6a..6557f6eed6 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -46,7 +46,14 @@ struct Statement { int _quotient; int _talkMap; - void synchronize(Common::SeekableReadStream &s, bool voices); + void synchronize(Common::SeekableReadStream &s); +}; + +struct TalkHistoryEntry { + bool _data[16]; + + TalkHistoryEntry(); + bool &operator[](int index) { return _data[index]; } }; class SherlockEngine; @@ -59,9 +66,14 @@ private: Common::Array _savedSequences; Common::Stack _sequenceStack; Common::Array _statements; + TalkHistoryEntry _talkHistory[500]; int _speaker; int _talkIndex; int _talkTo; + int _scriptSelect; + int _converseNum; + int _talkStealth; + int _talkToFlag; void pullSequence(); @@ -69,7 +81,10 @@ private: void clearTalking(); + void stripVoiceCommands(); void setTalkMap(); + + void displayTalk(bool slamIt); public: bool _talkToAbort; int _talkCounter; @@ -81,6 +96,8 @@ public: void talk(int objNum); void freeTalkVars(); + + void drawInterface(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 9fe8a0979f..74142ab80e 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -471,6 +471,16 @@ void UserInterface::clearInfo() { } } +/** + * Clear any active text window + */ +void UserInterface::clearWindow() { + if (_windowOpen) { + _vm->_screen->vgaBar(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, + SHERLOCK_SCREEN_HEIGHT - 2), INV_BACKGROUND); + } +} + /** * Handles counting down whilst checking for input, then clears the info line. */ diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index 157900f0aa..1259bed31b 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -50,6 +50,7 @@ enum MenuMode { SETUP_MODE = 12 }; +extern const char COMMANDS[13]; extern const int MENU_POINTS[12][4]; extern const int INVENTORY_POINTS[8][3]; @@ -132,6 +133,7 @@ public: void handleInput(); void clearInfo(); + void clearWindow(); void whileMenuCounter(); -- cgit v1.2.3 From 0b873d74e0a607ddf460c91fc6e18d04c7fb7b8c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 31 Mar 2015 08:28:51 -0400 Subject: SHERLOCK: Implemented displayTalk --- engines/sherlock/screen.h | 3 +- engines/sherlock/talk.cpp | 95 ++++++++++++++++++++++++++++++++++++++++++++++- engines/sherlock/talk.h | 8 +++- 3 files changed, 102 insertions(+), 4 deletions(-) diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 597c47c83a..edc0136471 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -49,7 +49,8 @@ enum { BUTTON_TOP = 233, BUTTON_MIDDLE = 244, BUTTON_BOTTOM = 248, - TALK_FOREGROUND = 12 + TALK_FOREGROUND = 12, + TALK_NULL = 16 }; class SherlockEngine; diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index e3c5ebc5e0..e915169903 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -22,6 +22,7 @@ #include "sherlock/talk.h" #include "sherlock/sherlock.h" +#include "sherlock/screen.h" namespace Sherlock { @@ -83,6 +84,7 @@ Talk::Talk(SherlockEngine *vm): _vm(vm) { _converseNum = -1; _talkStealth = 0; _talkToFlag = -1; + _moreTalkDown = _moreTalkUp = false; } /** @@ -405,6 +407,7 @@ void Talk::talkTo(const Common::String &filename) { } void Talk::talk(int objNum) { + // TODO } @@ -510,8 +513,98 @@ void Talk::drawInterface() { // TODO } -void Talk::displayTalk(bool slamIt) { +/** + * Display a list of statements in a window at the bottom of the scren that the + * player can select from. + */ +bool Talk::displayTalk(bool slamIt) { + Screen &screen = *_vm->_screen; + int yp = CONTROLS_Y + 14; + int lineY = -1; + _moreTalkDown = _moreTalkUp = false; + + for (uint idx = 0; idx < _statements.size(); ++idx) { + _statements[idx]._talkPos.top = _statements[idx]._talkPos.bottom = -1; + } + + if (_talkIndex) { + for (uint idx = 0; idx < _statements.size(); ++idx) { + if (_statements[idx]._talkMap != -1) + _moreTalkUp = true; + } + } + + // Display the up arrow if the first option is scrolled off-screen + if (_moreTalkUp) { + if (slamIt) { + screen.print(Common::Point(5, CONTROLS_Y + 13), INV_FOREGROUND, "~"); + screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_FOREGROUND, true, "Up"); + } else { + screen.gPrint(Common::Point(5, CONTROLS_Y + 12), INV_FOREGROUND, "~"); + screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_FOREGROUND, false, "Up"); + } + } else { + if (slamIt) { + screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_NULL, true, "Up"); + screen.vgaBar(Common::Rect(5, CONTROLS_Y + 11, 15, CONTROLS_Y + 22), INV_BACKGROUND); + } else { + screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_NULL, false, "Up"); + screen._backBuffer1.fillRect(Common::Rect(5, CONTROLS_Y + 11, + 15, CONTROLS_Y + 22), INV_BACKGROUND); + } + } + + // Loop through the statements + bool done = false; + for (uint idx = _talkIndex; idx < _statements.size() && !done; ++idx) { + Statement &statement = _statements[idx]; + + if (statement._talkMap != -1) { + bool flag = _talkHistory[_converseNum][idx]; + lineY = talkLine(idx, statement._talkMap, flag ? TALK_NULL : INV_FOREGROUND, + yp, slamIt); + + if (lineY != -1) { + statement._talkPos.top = yp; + yp = lineY; + statement._talkPos.bottom = yp; + + if (yp == SHERLOCK_SCREEN_HEIGHT) + done = true; + } else { + done = true; + } + } + } + + // Display the down arrow if there are more statements available + if (lineY == -1 || lineY == SHERLOCK_SCREEN_HEIGHT) { + _moreTalkDown = true; + + if (slamIt) { + screen.print(Common::Point(5, 190), INV_FOREGROUND, "|"); + screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_FOREGROUND, true, "Down"); + } else { + screen.gPrint(Common::Point(5, 189), INV_FOREGROUND, "|"); + screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_FOREGROUND, false, "Down"); + } + } else { + if (slamIt) { + screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, true, "Down"); + screen.vgaBar(Common::Rect(5, 189, 16, 199), INV_BACKGROUND); + } else { + screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_FOREGROUND, false, "Down"); + screen._backBuffer1.fillRect(Common::Rect(5, 189, 16, 199), INV_BACKGROUND); + } + } + + return done; +} + +int Talk::talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt) { // TODO + return 0; } + } // End of namespace Sherlock diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index 6557f6eed6..d44419f9a9 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -25,6 +25,7 @@ #include "common/scummsys.h" #include "common/array.h" +#include "common/rect.h" #include "common/stream.h" #include "common/stack.h" @@ -45,6 +46,7 @@ struct Statement { int _portraitSide; int _quotient; int _talkMap; + Common::Rect _talkPos; void synchronize(Common::SeekableReadStream &s); }; @@ -59,7 +61,6 @@ struct TalkHistoryEntry { class SherlockEngine; class Talk { - private: SherlockEngine *_vm; int _saveSeqNum; @@ -74,6 +75,7 @@ private: int _converseNum; int _talkStealth; int _talkToFlag; + bool _moreTalkUp, _moreTalkDown; void pullSequence(); @@ -84,7 +86,9 @@ private: void stripVoiceCommands(); void setTalkMap(); - void displayTalk(bool slamIt); + bool displayTalk(bool slamIt); + + int talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt); public: bool _talkToAbort; int _talkCounter; -- cgit v1.2.3 From 87521eb504ddb8f05c6b61cfdaf3c757f5adce64 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 31 Mar 2015 20:16:34 -0400 Subject: SHERLOCK: Implemented talkLine --- engines/sherlock/talk.cpp | 91 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index e915169903..a84ce7cd70 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -601,10 +601,95 @@ bool Talk::displayTalk(bool slamIt) { return done; } +/** + * Prints a single conversation option in the interface window + */ int Talk::talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt) { - // TODO - return 0; -} + Screen &screen = *_vm->_screen; + int idx = lineNum; + Common::String msg, number; + bool numberFlag = false; + + // Get the statement to display as well as optional number prefix + if (idx < 128) { + number = Common::String::format("%d.", stateNum + 1); + numberFlag = true; + } else { + idx -= 128; + } + msg = _statements[idx]._statement; + + // Handle potentially multiple lines needed to display entire statement + const char *lineStartP = msg.c_str(); + int maxWidth = 298 - numberFlag ? 18 : 0; + for (;;) { + // Get as much of the statement as possible will fit on the + Common::String sLine; + const char *lineEndP = lineStartP; + int width = 0; + do { + width += screen.charWidth(*lineEndP); + } while (*++lineEndP && width < maxWidth); + + // Check if we need to wrap the line + if (width >= maxWidth) { + // Work backwards to the prior word's end + while (*--lineEndP != ' ') + ; + + sLine = Common::String(lineStartP, lineEndP++); + } else { + // Can display remainder of the statement on the current line + sLine = Common::String(lineStartP); + } + + + if (lineY <= (SHERLOCK_SCREEN_HEIGHT - 10)) { + // Need to directly display on-screen? + if (slamIt) { + // See if a numer prefix is needed or not + if (numberFlag) { + // Are we drawing the first line? + if (lineStartP == msg.c_str()) { + // We are, so print the number and then the text + screen.print(Common::Point(16, lineY), color, number.c_str()); + } + + // Draw the line with an indent + screen.print(Common::Point(30, lineY), color, sLine.c_str()); + } else { + screen.print(Common::Point(16, lineY), color, sLine.c_str()); + } + } else { + if (numberFlag) { + if (lineStartP == msg.c_str()) { + screen.gPrint(Common::Point(16, lineY - 1), color, number.c_str()); + } + + screen.gPrint(Common::Point(30, lineY - 1), color, sLine.c_str()); + } else { + screen.gPrint(Common::Point(16, lineY - 1), color, sLine.c_str()); + } + } + // Move to next line, if any + lineY += 9; + lineStartP = lineEndP; + + if (!*lineEndP) + break; + } else { + // We're close to the bottom of the screen, so stop display + lineY = -1; + break; + } + } + + if (lineY == -1 && lineStartP != msg.c_str()) + lineY = SHERLOCK_SCREEN_HEIGHT; + + // Return the Y position of the next line to follow this one + return lineY; +} } // End of namespace Sherlock -- cgit v1.2.3 From 54ecf6cda88f6a32b0e12f9fdb2698c540d76bd4 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 31 Mar 2015 20:37:59 -0400 Subject: SHERLOCK: Implemented talk method --- engines/sherlock/talk.cpp | 97 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index a84ce7cd70..e5d6cea64a 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -406,9 +406,104 @@ void Talk::talkTo(const Common::String &filename) { events.setCursor(ARROW); } +/** + * Main method for handling conversations when a character to talk to has been + * selected. It will make Holmes walk to the person to talk to, draws the + * interface window for the conversation and passes on control to give the + * player a list of options to make a selection from + */ void Talk::talk(int objNum) { + Events &events = *_vm->_events; + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + Screen &screen = *_vm->_screen; + Scripts &scripts = *_vm->_scripts; + UserInterface &ui = *_vm->_ui; + Object &obj = scene._bgShapes[objNum]; - // TODO + ui._windowBounds.top = CONTROLS_Y; + ui._infoFlag = true; + _speaker = 128; + loadTalkFile(scene._bgShapes[objNum]._name); + + // Find the first statement with the correct flags + int select = -1; + for (uint idx = 0; idx < _statements.size(); ++idx) { + if (_statements[idx]._talkMap == 0) { + select = idx; + break; + } + } + if (select == -1) + error("No entry matched all required flags"); + + // See if the statement is a stealth mode reply + Statement &statement = _statements[select]; + if (statement._statement.hasPrefix("^")) { + _sequenceStack.clear(); + + // Start talk in stealth mode + _talkStealth = 2; + + talkTo(obj._name); + } else if (statement._statement.hasPrefix("*")) { + // Character being spoken to will speak first + _sequenceStack.clear(); + scripts.pushSeq(_talkTo); + scripts.setStillSeq(_talkTo); + + events.setCursor(WAIT); + if (obj._lookPosition.y != 0) + // Need to walk to character first + people.walkToCoords(Common::Point(obj._lookPosition.x, obj._lookPosition.y * 100), + obj._lookFacing); + events.setCursor(ARROW); + + if (_talkToAbort) + talkTo(obj._name); + } else { + // Holmes will be speaking first + _sequenceStack.clear(); + scripts.pushSeq(_talkTo); + scripts.setStillSeq(_talkTo); + + _talkToFlag = false; + events.setCursor(WAIT); + if (obj._lookPosition.y != 0) + // Walk over to person to talk to + people.walkToCoords(Common::Point(obj._lookPosition.x, obj._lookPosition.y * 100), + obj._lookFacing); + events.setCursor(ARROW); + + if (!_talkToAbort) { + // See if walking over triggered a conversation + if (_talkToFlag) { + if (_talkToFlag == 1) { + events.setCursor(ARROW); + // _sequenceStack._count = 1; + scripts.pullSeq(); + } + } else { + drawInterface(); + + events._pressed = events._released = false; + _talkIndex = select; + displayTalk(false); + ui._selector = ui._oldSelector = -1; + + if (!ui._windowStyle) { + screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, + SHERLOCK_SCREEN_HEIGHT)); + } else { + ui.summonWindow(); + } + + ui._windowOpen = true; + } + + _talkToFlag = -1; + } + } } /** -- cgit v1.2.3 From 8fa8b14762ce655d0d99782864be927d3c946cba Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 31 Mar 2015 21:30:22 -0400 Subject: SHERLOCK: Implement clearTalking and Talk::drawInterface --- engines/sherlock/people.cpp | 36 ++++++++++++++++++++++++++++++++++++ engines/sherlock/people.h | 4 ++++ engines/sherlock/talk.cpp | 35 +++++++++++++++++++++++++++++------ engines/sherlock/talk.h | 2 -- engines/sherlock/user_interface.h | 2 ++ 5 files changed, 71 insertions(+), 8 deletions(-) diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index ca840bb5b1..8d4fa68117 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -57,13 +57,16 @@ People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) { _oldWalkSequence = -1; _allowWalkAbort = false; _portraitLoaded = false; + _portraitsOn = false; _clearingThePortrait = false; _srcZone = _destZone = 0; + _talkPics = nullptr; } People::~People() { if (_walkLoaded) delete _data[PLAYER]._images; + delete _talkPics; } void People::reset() { @@ -434,4 +437,37 @@ void People::goAllTheWay() { } } +/** + * Turn off any currently active portraits, and removes them from being drawn + */ +void People::clearTalking() { + Scene &scene = *_vm->_scene; + Screen &screen = *_vm->_screen; + Talk &talk = *_vm->_talk; + + if (_portraitsOn) { + Common::Point pt = _portrait._position; + int width, height; + _portrait._imageFrame = _talkPics ? &(*_talkPics)[0] : (ImageFrame *)nullptr; + + // Flag portrait for removal, and save the size of the frame to use erasing it + _portrait._type = REMOVE; + _portrait._delta.x = width = _portrait.frameWidth(); + _portrait._delta.y = height = _portrait.frameHeight(); + + delete _talkPics; + _talkPics = nullptr; + + // Flag to let the talk code know not to interrupt on the next doBgAnim + _clearingThePortrait = true; + scene.doBgAnim(); + _clearingThePortrait = false; + + screen.slamArea(pt.x, pt.y, width, height); + + if (!talk._talkToAbort) + _portraitLoaded = false; + } +} + } // End of namespace Sherlock diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index 6b5c59b1bd..1c67ff8996 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -66,12 +66,14 @@ private: bool _walkLoaded; int _oldWalkSequence; int _srcZone, _destZone; + ImageFile *_talkPics; public: Common::Point _walkDest; Common::Stack _walkTo; Person &_player; bool _holmesOn; bool _portraitLoaded; + bool _portraitsOn; Object _portrait; bool _clearingThePortrait; bool _allowWalkAbort; @@ -96,6 +98,8 @@ public: void walkToCoords(const Common::Point &destPos, int destDir); void goAllTheWay(); + + void clearTalking(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index e5d6cea64a..79f9167506 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -190,7 +190,7 @@ void Talk::talkTo(const Common::String &filename) { case TALK_MODE: if (_speaker < 128) - clearTalking(); + people.clearTalking(); if (_talkCounter) return; @@ -554,10 +554,6 @@ void Talk::loadTalkFile(const Common::String &filename) { setTalkMap(); } -void Talk::clearTalking() { - // TODO -} - /** * Remove any voice commands from a loaded statement list */ @@ -604,8 +600,35 @@ void Talk::setTalkMap() { } } +/** + * Draws the interface for conversation display + */ void Talk::drawInterface() { - // TODO + Screen &screen = *_vm->_screen; + Surface &bb = *screen._backBuffer; + + bb.fillRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y1 + 10), BORDER_COLOR); + bb.fillRect(Common::Rect(0, CONTROLS_Y + 10, 2, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); + bb.fillRect(Common::Rect(SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y + 10, + SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); + bb.fillRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - 1, SHERLOCK_SCREEN_WIDTH - 2, + SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); + bb.fillRect(Common::Rect(2, CONTROLS_Y + 10, SHERLOCK_SCREEN_WIDTH - 2, + SHERLOCK_SCREEN_HEIGHT - 2), INV_BACKGROUND); + + if (_talkTo != -1) { + screen.makeButton(Common::Rect(99, CONTROLS_Y, 139, CONTROLS_Y + 10), + 119 - screen.stringWidth("Exit") / 2, "Exit"); + screen.makeButton(Common::Rect(140, CONTROLS_Y, 180, CONTROLS_Y + 10), + 159 - screen.stringWidth("Up"), "Up"); + screen.makeButton(Common::Rect(181, CONTROLS_Y, 221, CONTROLS_Y + 10), + 200 - screen.stringWidth("Down") / 2, "Down"); + } else { + int strWidth = screen.stringWidth(PRESS_KEY_TO_CONTINUE); + screen.makeButton(Common::Rect(46, CONTROLS_Y, 273, CONTROLS_Y + 10), + 160 - strWidth, PRESS_KEY_TO_CONTINUE); + screen.gPrint(Common::Point(160 - strWidth / 2, CONTROLS_Y), COMMAND_FOREGROUND, false, "P"); + } } /** diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index d44419f9a9..dbcdf742b8 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -81,8 +81,6 @@ private: void loadTalkFile(const Common::String &filename); - void clearTalking(); - void stripVoiceCommands(); void setTalkMap(); diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index 1259bed31b..f80fe48b2d 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -55,6 +55,8 @@ extern const int MENU_POINTS[12][4]; extern const int INVENTORY_POINTS[8][3]; extern const char INVENTORY_COMMANDS[9]; +extern const char *const PRESS_KEY_FOR_MORE; +extern const char *const PRESS_KEY_TO_CONTINUE; class SherlockEngine; class Inventory; -- cgit v1.2.3 From 1199cf724c7507fb54a52eea842ac2bcc6864736 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 31 Mar 2015 22:42:57 -0400 Subject: SHERLOCK: Loading for TALK_SEQUENCES and STILL_SEQUENCES Scalpel arrays --- engines/sherlock/people.cpp | 5 ++ engines/sherlock/people.h | 2 + engines/sherlock/scalpel/scalpel.cpp | 145 +++++++++++++++++++++++++++++++++++ engines/sherlock/scripts.cpp | 12 --- engines/sherlock/scripts.h | 6 -- engines/sherlock/talk.cpp | 100 +++++++++++++++++++----- engines/sherlock/talk.h | 27 ++++++- 7 files changed, 257 insertions(+), 40 deletions(-) diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 8d4fa68117..3da35f2fec 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -470,4 +470,9 @@ void People::clearTalking() { } } +int People::findSpeaker(int speaker) { + // TODO + return -1; +} + } // End of namespace Sherlock diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index 1c67ff8996..aa54c67567 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -100,6 +100,8 @@ public: void goAllTheWay(); void clearTalking(); + + int findSpeaker(int speaker); }; } // End of namespace Sherlock diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index d226c2e82a..0432dc2278 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -39,6 +39,148 @@ const int MAP_Y[NUM_PLACES] = { 37, 0, 70, 0, 116, 0, 0, 0, 50, 21, 0, 303, 0, 0, 229, 0, 0 }; +#define MAX_PEOPLE 66 + +const byte STILL_SEQUENCES[MAX_PEOPLE][MAX_TALK_SEQUENCES] = { + { 1, 0, 0 }, // Sherlock Holmes + { 6, 0, 0 }, // Dr. Watson + { 4, 0, 0 }, // Inspector Lestrade + { 2, 0, 0 }, // Constable #1 + { 2, 0, 0 }, // Constable #2 + { 2, 0, 0 }, // Sheila Parker + { 3, 0, 0 }, // Henry Carruthers + { 9, 0, 0 }, // Lesly (flower girl) + { 13, 0, 0 }, // Usher #1 + { 2, 0, 0 }, // Usher #2 + { 4, 0, 0 }, // Fredrick Epstein + { 9, 0, 0 }, // Mrs.Worthington + { 2, 0, 0 }, // Coach + { 8, 0, 0 }, // Player + { 13, 0, 0 }, // Waterboy + { 6, 0, 0 }, // James Sanders + { 1, 0, 0 }, // Belle (perfumerie) + { 20, 0, 0 }, // Cleaning Girl (perfumerie) + { 17, 0, 0 }, // Epstien in the Opera Balcony + { 3, 0, 0 }, // Wiggins + { 2, 0, 0 }, // Paul (Brumwell/Carroway) + { 1, 0, 0 }, // Bartender + { 1, 0, 0 }, // Dirty Drunk + { 1, 0, 0 }, // Shouting Drunk + { 1, 0, 0 }, // Staggering Drunk + { 1, 0, 0 }, // Bouncer + { 6, 0, 0 }, // James Sanders - At Home + { 6, 0, 0 }, // The Coroner + { 1, 0, 0 }, // The Equestrian Shop Keeper + { 1, 0, 0 }, // George Blackwood + { 7, 0, 0 }, // Lars + { 1, 0, 0 }, // Sheila Parker + { 8, 0, 0 }, // Chemist + { 6, 0, 0 }, // Inspector Gregson + { 1, 0, 0 }, // Lawyer + { 1, 0, 0 }, // Mycroft + { 7, 0, 0 }, // Old Sherman + { 1, 0, 0 }, // Stock Boy in Chemist Shop + { 1, 0, 0 }, // Barman + { 1, 0, 0 }, // Dandy Player + { 1, 0, 0 }, // Rough-looking Player + { 1, 0, 0 }, // Spectator + { 1, 0, 0 }, // Robert Hunt + { 3, 0, 0 }, // Violet Secretary + { 1, 0, 0 }, // Pettigrew + { 8, 0, 0 }, // Augie (apple seller) + { 16, 0, 0 }, // Anna Carroway + { 1, 0, 0 }, // Guard + { 8, 0, 0 }, // Antonio Caruso + { 1, 0, 0 }, // Toby the Dog + { 13, 0, 0 }, // Simon Kingsley + { 2, 0, 0 }, // Alfred Tobacco Clerk + { 1, 0, 0 }, // Lady Brumwell + { 1, 0, 0 }, // Madame Rosa + { 1, 0, 0 }, // Lady Brumwell + { 1, 0, 0 }, // Joseph Moorehead + { 5, 0, 0 }, // Mrs. Beale + { 1, 0, 0 }, // Felix the Lion + { 1, 0, 0 }, // Hollingston + { 1, 0, 0 }, // Constable Callaghan + { 2, 0, 0 }, // Sergeant Jeremy Duncan + { 1, 0, 0 }, // Lord Brumwell + { 1, 0, 0 }, // Nigel Jameson + { 1, 0, 0 }, // Jonas (newspaper seller) + { 1, 0, 0 }, // Constable Dugan + { 4, 0, 0 } // Inspector Lestrade (Yard) +}; + +byte TALK_SEQUENCES[MAX_PEOPLE][MAX_TALK_SEQUENCES] = { + { 1, 0, 0 }, // Sherlock Holmes + { 5, 5, 6, 7, 8, 7, 8, 6, 0, 0 }, // Dr. Watson + { 2, 0, 0 }, // Inspector Lestrade + { 1, 0, 0 }, // Constable #1 + { 1, 0, 0 }, // Constable #2 + { 2, 3, 0, 0 }, // Sheila Parker + { 3, 0, 0 }, // Henry Carruthers + { 1, 2, 3, 2, 1, 2, 3, 0, 0 }, // Lesly (flower girl) + { 13, 14, 0, 0 }, // Usher #1 + { 2, 0, 0 }, // Usher #2 + { 1, 2, 3, 4, 3, 4, 3, 2, 0, 0 }, // Fredrick Epstein + { 8, 0, 0 }, // Mrs.Worthington + { 1, 2, 3, 4, 5, 4, 3, 2, 0, 0 }, // Coach + { 7, 8, 0, 0 }, // Player + { 12, 13, 0, 0 }, // Waterboy + { 3, 4, 0, 0 }, // James Sanders + { 4, 5, 0, 0 }, // Belle (perfumerie) + { 14, 15, 16, 17, 18, 19, 20, 20, 20, 0, 0 }, // Cleaning Girl (perfumerie) + { 16, 17, 18, 18, 18, 17, 17, 0, 0 }, // Epstien in the Opera Balcony + { 2, 3, 0, 0 }, // Wiggins + { 1, 2, 0, 0 }, // Paul (Brumwell/Carroway) + { 1, 0, 0 }, // Bartender + { 1, 0, 0 }, // Dirty Drunk + { 1, 0, 0 }, // Shouting Drunk + { 1, 0, 0 }, // Staggering Drunk + { 1, 0, 0 }, // Bouncer + { 5, 6, 0, 0 }, // James Sanders - At Home + { 4, 5, 0, 0 }, // The Coroner + { 1, 0, 0 }, // The Equestrian Shop Keeper + { 1, 0, 0 }, // George Blackwood + { 5, 6, 0, 0 }, // Lars + { 1, 0, 0 }, // Sheila Parker + { 8, 9, 0, 0 }, // Chemist + { 5, 6, 0, 0 }, // Inspector Gregson + { 1, 0, 0 }, // Lawyer + { 1, 0, 0 }, // Mycroft + { 7, 8, 0, 0 }, // Old Sherman + { 1, 0, 0 }, // Stock Boy in Chemist Shop + { 1, 0, 0 }, // Barman + { 1, 0, 0 }, // Dandy Player + { 1, 0, 0 }, // Rough-looking Player + { 1, 0, 0 }, // Spectator + { 1, 0, 0 }, // Robert Hunt + { 3, 4, 0, 0 }, // Violet Secretary + { 1, 0, 0 }, // Pettigrew + { 14, 15, 0, 0 }, // Augie (apple seller) + { 3, 4, 5, 6, 0, 0 }, // Anna Carroway + { 4, 5, 6, 0, 0 }, // Guard + { 7, 8, 0, 0 }, // Antonio Caruso + { 1, 0, 0 }, // Toby the Dog + { 13, 14, 0, 0 }, // Simon Kingsley + { 2, 3, 0, 0 }, // Alfred Tobacco Clerk + { 3, 4, 0, 0 }, // Lady Brumwell + { 1, 30, 0, 0 }, // Madame Rosa + { 3, 4, 0, 0 }, // Lady Brumwell + { 1, 0, 0 }, // Joseph Moorehead + { 14, 15, 16, 17, 18, 19, 20, 0, 0 }, // Mrs. Beale + { 1, 0, 0 }, // Felix the Lion + { 1, 0, 0 }, // Hollingston + { 1, 0, 0 }, // Constable Callaghan + { 1, 1, 2, 2, 0, 0 }, // Sergeant Jeremy Duncan + { 9, 10, 0, 0 }, // Lord Brumwell + { 1, 2, 0, 138, 3, 4, 0, 138, 0, 0 }, // Nigel Jameson + { 1, 8, 0, 0 }, // Jonas (newspaper seller) + { 1, 0, 0 }, // Constable Dugan + { 2, 0, 0 } // Inspector Lestrade (Yard) +}; + +/*----------------------------------------------------------------*/ + ScalpelEngine::ScalpelEngine(OSystem *syst, const SherlockGameDescription *gameDesc) : SherlockEngine(syst, gameDesc) { _chess = nullptr; @@ -71,6 +213,9 @@ void ScalpelEngine::initialize() { // Load the inventory loadInventory(); + // Set up constants used by the talk system + _talk->setSequences(&TALK_SEQUENCES[0][0], &STILL_SEQUENCES[0][0], MAX_PEOPLE); + // Starting scene _scene->_goToScene = 4; } diff --git a/engines/sherlock/scripts.cpp b/engines/sherlock/scripts.cpp index 1da72c976b..d337030bae 100644 --- a/engines/sherlock/scripts.cpp +++ b/engines/sherlock/scripts.cpp @@ -35,18 +35,6 @@ void Scripts::doScript(const Common::String &str) { // TODO } -void Scripts::pullSeq() { - // TODO -} - -void Scripts::pushSeq(int speak) { - // TODO -} - -void Scripts::setStillSeq(int speak) { - // TODO -} - void Scripts::popStack() { ScriptEntry script = _scriptStack.pop(); _scriptName = script._name; diff --git a/engines/sherlock/scripts.h b/engines/sherlock/scripts.h index 6c23e72fe4..6765687bcf 100644 --- a/engines/sherlock/scripts.h +++ b/engines/sherlock/scripts.h @@ -50,12 +50,6 @@ public: void doScript(const Common::String &str); - void pullSeq(); - - void pushSeq(int speak); - - void setStillSeq(int speak); - void popStack(); }; diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 79f9167506..26c2e523f3 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -73,6 +73,16 @@ TalkHistoryEntry::TalkHistoryEntry() { /*----------------------------------------------------------------*/ +TalkSequences::TalkSequences(const byte *data) { + Common::copy(data, data + MAX_TALK_SEQUENCES, _data); +} + +void TalkSequences::clear() { + Common::fill(&_data[0], &_data[MAX_TALK_SEQUENCES], 0); +} + +/*----------------------------------------------------------------*/ + Talk::Talk(SherlockEngine *vm): _vm(vm) { _talkCounter = 0; _talkToAbort = false; @@ -87,6 +97,15 @@ Talk::Talk(SherlockEngine *vm): _vm(vm) { _moreTalkDown = _moreTalkUp = false; } +void Talk::setSequences(const byte *talkSequences, const byte *stillSequences, int maxPeople) { + for (int idx = 0; idx < maxPeople; ++idx) { + STILL_SEQUENCES.push_back(TalkSequences(stillSequences)); + TALK_SEQUENCES.push_back(TalkSequences(talkSequences)); + stillSequences += MAX_TALK_SEQUENCES; + talkSequences += MAX_TALK_SEQUENCES; + } +} + /** * Called when either an NPC initiates a conversation or for inventory item * descriptions. It opens up a description window similar to how 'talk' does, @@ -158,7 +177,7 @@ void Talk::talkTo(const Common::String &filename) { } } - while (_sequenceStack.empty()) + while (!_sequenceStack.empty()) pullSequence(); // Restore any pressed button @@ -283,7 +302,7 @@ void Talk::talkTo(const Common::String &filename) { // Handle replies until there's no further linked file, // or the link file isn't a reply first cnversation for (;;) { - _sequenceStack.clear(); + clearSequences(); _scriptSelect = select; _speaker = _talkTo; @@ -318,7 +337,7 @@ void Talk::talkTo(const Common::String &filename) { } if (_talkToFlag == 1) - scripts.pullSeq(); + pullSequence(); // Set the stealth mode for the new talk file Statement &newStatement = _statements[select]; @@ -328,9 +347,9 @@ void Talk::talkTo(const Common::String &filename) { // to display any choices, since the reply needs to be shown if (!newStatement._statement.hasPrefix("*") && !newStatement._statement.hasPrefix("^")) { - _sequenceStack.clear(); - scripts.pushSeq(_talkTo); - scripts.setStillSeq(_talkTo); + clearSequences(); + pushSequence(_talkTo); + setStillSeq(_talkTo); _talkIndex = select; ui._selector = ui._oldSelector = -1; @@ -417,7 +436,6 @@ void Talk::talk(int objNum) { People &people = *_vm->_people; Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; - Scripts &scripts = *_vm->_scripts; UserInterface &ui = *_vm->_ui; Object &obj = scene._bgShapes[objNum]; @@ -440,7 +458,7 @@ void Talk::talk(int objNum) { // See if the statement is a stealth mode reply Statement &statement = _statements[select]; if (statement._statement.hasPrefix("^")) { - _sequenceStack.clear(); + clearSequences(); // Start talk in stealth mode _talkStealth = 2; @@ -448,9 +466,9 @@ void Talk::talk(int objNum) { talkTo(obj._name); } else if (statement._statement.hasPrefix("*")) { // Character being spoken to will speak first - _sequenceStack.clear(); - scripts.pushSeq(_talkTo); - scripts.setStillSeq(_talkTo); + clearSequences(); + pushSequence(_talkTo); + setStillSeq(_talkTo); events.setCursor(WAIT); if (obj._lookPosition.y != 0) @@ -463,9 +481,9 @@ void Talk::talk(int objNum) { talkTo(obj._name); } else { // Holmes will be speaking first - _sequenceStack.clear(); - scripts.pushSeq(_talkTo); - scripts.setStillSeq(_talkTo); + clearSequences(); + pushSequence(_talkTo); + setStillSeq(_talkTo); _talkToFlag = false; events.setCursor(WAIT); @@ -481,7 +499,7 @@ void Talk::talk(int objNum) { if (_talkToFlag == 1) { events.setCursor(ARROW); // _sequenceStack._count = 1; - scripts.pullSeq(); + pullSequence(); } } else { drawInterface(); @@ -513,10 +531,6 @@ void Talk::freeTalkVars() { _statements.clear(); } -void Talk::pullSequence() { - // TODO -} - /** * Opens the talk file 'talk.tlk' and searches the index for the specified * conversation. If found, the data for that conversation is loaded @@ -810,4 +824,52 @@ int Talk::talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt return lineY; } +/** + * Clears the stack of pending object sequences associated with speakers in the scene + */ +void Talk::clearSequences() { + _sequenceStack.clear(); +} + +void Talk::pullSequence() { + // TODO +} + +void Talk::pushSequence(int speak) { + // TODO +} + +/** + * Change the sequence of a background object corresponding to a given speaker. + * The new sequence will display the character as "listening" + */ +void Talk::setStillSeq(int speak) { + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + + // Don't bother doing anything if no specific speaker is specified + if (speak == -1) + return; + + if (speak) { + int objNum = people.findSpeaker(speak); + if (objNum != -1) { + Object &obj = scene._bgShapes[objNum]; + + if (obj._seqSize < MAX_TALK_SEQUENCES) { + warning("Tried to copy too many still frames"); + } else { + for (uint idx = 0; idx < MAX_TALK_SEQUENCES; ++idx) { + obj._sequences[idx] = STILL_SEQUENCES[speak][idx]; + if (idx > 0 && !TALK_SEQUENCES[speak][idx] && !TALK_SEQUENCES[speak][idx - 1]) + break; + } + + obj._frameNumber = 0; + obj._seqTo = 0; + } + } + } +} + } // End of namespace Sherlock diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index dbcdf742b8..3b02f92bc6 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -31,6 +31,8 @@ namespace Sherlock { +#define MAX_TALK_SEQUENCES 11 + struct SavedSequence { int _objNum; Common::Array _sequences; @@ -58,15 +60,28 @@ struct TalkHistoryEntry { bool &operator[](int index) { return _data[index]; } }; +struct TalkSequences { + byte _data[MAX_TALK_SEQUENCES]; + + TalkSequences() { clear(); } + TalkSequences(const byte *data); + + byte &operator[](int idx) { return _data[idx]; } + void clear(); +}; + class SherlockEngine; class Talk { +private: + Common::Array STILL_SEQUENCES; + Common::Array TALK_SEQUENCES; private: SherlockEngine *_vm; int _saveSeqNum; Common::Array _savedSequences; - Common::Stack _sequenceStack; Common::Array _statements; + Common::Stack _sequenceStack; TalkHistoryEntry _talkHistory[500]; int _speaker; int _talkIndex; @@ -77,8 +92,6 @@ private: int _talkToFlag; bool _moreTalkUp, _moreTalkDown; - void pullSequence(); - void loadTalkFile(const Common::String &filename); void stripVoiceCommands(); @@ -92,6 +105,8 @@ public: int _talkCounter; public: Talk(SherlockEngine *vm); + void setSequences(const byte *talkSequences, const byte *stillSequences, + int maxPeople); void talkTo(const Common::String &filename); @@ -100,6 +115,12 @@ public: void freeTalkVars(); void drawInterface(); + + void setStillSeq(int speak); + void clearSequences(); + void pullSequence(); + void pushSequence(int speak); + bool isSequencesEmpty() const { return _sequenceStack.empty(); } }; } // End of namespace Sherlock -- cgit v1.2.3 From 283c6074ad77c0c18c9d1550d7ac7c2443072aec Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 31 Mar 2015 23:21:04 -0400 Subject: SHERLOCK: Implement pushSequence and pullSequence --- engines/sherlock/talk.cpp | 66 ++++++++++++++++++++++++++++++++++++++++------- engines/sherlock/talk.h | 11 +++++--- 2 files changed, 64 insertions(+), 13 deletions(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 26c2e523f3..6596431b8b 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -831,37 +831,83 @@ void Talk::clearSequences() { _sequenceStack.clear(); } +/** + * Pulls a background object sequence from the sequence stack and restore's the + * object's sequence + */ void Talk::pullSequence() { - // TODO + Scene &scene = *_vm->_scene; + + SequenceEntry seq = _sequenceStack.pop(); + if (seq._objNum != -1) { + Object &obj = scene._bgShapes[seq._objNum]; + + if (obj._seqSize < MAX_TALK_SEQUENCES) { + warning("Tried to restore too few frames"); + } else { + for (int idx = 0; idx < MAX_TALK_SEQUENCES; ++idx) + obj._sequences[idx] = seq._sequences[idx]; + + obj._frameNumber = seq._frameNumber; + obj._seqTo = seq._seqTo; + } + } } -void Talk::pushSequence(int speak) { - // TODO +/** + * Push the sequence of a background object that's an NPC that needs to be + * saved onto the sequence stack. + */ +void Talk::pushSequence(int speaker) { + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + + // Only proceed if a speaker is specified + if (speaker == -1) + return; + + SequenceEntry seqEntry; + if (!speaker) { + seqEntry._objNum = -1; + } else { + seqEntry._objNum = people.findSpeaker(speaker); + + Object &obj = scene._bgShapes[seqEntry._objNum]; + for (uint idx = 0; idx < MAX_TALK_SEQUENCES; ++idx) + seqEntry._sequences.push_back(obj._sequences[idx]); + + seqEntry._frameNumber = obj._frameNumber; + seqEntry._seqTo = obj._seqTo; + } + + _sequenceStack.push(seqEntry); + if (_sequenceStack.size() >= 5) + error("sequence stack overflow"); } /** * Change the sequence of a background object corresponding to a given speaker. * The new sequence will display the character as "listening" */ -void Talk::setStillSeq(int speak) { +void Talk::setStillSeq(int speaker) { People &people = *_vm->_people; Scene &scene = *_vm->_scene; // Don't bother doing anything if no specific speaker is specified - if (speak == -1) + if (speaker == -1) return; - if (speak) { - int objNum = people.findSpeaker(speak); + if (speaker) { + int objNum = people.findSpeaker(speaker); if (objNum != -1) { Object &obj = scene._bgShapes[objNum]; if (obj._seqSize < MAX_TALK_SEQUENCES) { - warning("Tried to copy too many still frames"); + warning("Tried to copy too few still frames"); } else { for (uint idx = 0; idx < MAX_TALK_SEQUENCES; ++idx) { - obj._sequences[idx] = STILL_SEQUENCES[speak][idx]; - if (idx > 0 && !TALK_SEQUENCES[speak][idx] && !TALK_SEQUENCES[speak][idx - 1]) + obj._sequences[idx] = STILL_SEQUENCES[speaker][idx]; + if (idx > 0 && !TALK_SEQUENCES[speaker][idx] && !TALK_SEQUENCES[speaker][idx - 1]) break; } diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index 3b02f92bc6..0cd0a8c638 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -38,6 +38,11 @@ struct SavedSequence { Common::Array _sequences; }; +struct SequenceEntry : public SavedSequence { + int _frameNumber; + int _seqTo; +}; + struct Statement { Common::String _statement; Common::String _reply; @@ -80,8 +85,8 @@ private: SherlockEngine *_vm; int _saveSeqNum; Common::Array _savedSequences; + Common::Stack _sequenceStack; Common::Array _statements; - Common::Stack _sequenceStack; TalkHistoryEntry _talkHistory[500]; int _speaker; int _talkIndex; @@ -116,10 +121,10 @@ public: void drawInterface(); - void setStillSeq(int speak); + void setStillSeq(int speaker); void clearSequences(); void pullSequence(); - void pushSequence(int speak); + void pushSequence(int speaker); bool isSequencesEmpty() const { return _sequenceStack.empty(); } }; -- cgit v1.2.3 From c13c02b079d0881b4d1cd205364d043920bab9a5 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 1 Apr 2015 23:12:49 -0400 Subject: SHERLOCK: Implemented loadJournalFile --- engines/sherlock/journal.cpp | 379 +++++++++++++++++++++++++++++++++++++++++- engines/sherlock/journal.h | 30 +++- engines/sherlock/people.h | 1 + engines/sherlock/sherlock.cpp | 2 +- engines/sherlock/talk.h | 8 +- 5 files changed, 412 insertions(+), 8 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 34423d2480..a9eb86bf07 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -21,10 +21,11 @@ */ #include "sherlock/journal.h" +#include "sherlock/sherlock.h" namespace Sherlock { -Journal::Journal() { +Journal::Journal(SherlockEngine *vm): _vm(vm) { // Allow up to 1000 statements _data.resize(1000); @@ -35,10 +36,386 @@ Journal::Journal() { _sub = 0; _up = _down = 0; _page = 0; + _converseNum = -1; + + // Load the journal directory and location names + loadJournalLocations(); } +/** + * Records statements that are said, in the order which they are said. The player + * can then read the journal to review them + */ void Journal::record(int converseNum, int statementNum) { + int saveIndex = _index; + int saveSub = _sub; + + // Record the entry into the list + _data.push_back(JournalEntry(converseNum, statementNum)); + + bool newLines = loadJournalFile(true); + // TODO } +void Journal::loadJournalLocations() { + Resources &res = *_vm->_res; + char c; + + _directory.clear(); + + Common::SeekableReadStream *dir = res.load("talk.lib"); + dir->skip(4); // Skip header + + // Get the numer of entries + _directory.resize(dir->readUint16LE()); + + // Read in each entry + for (uint idx = 0; idx < _directory.size(); ++idx) { + Common::String line; + while ((c = dir->readByte()) != 0) + line += c; + + _directory.push_back(line); + } + + delete dir; + + // Load in the locations stored in journal.txt + Common::SeekableReadStream *loc = res.load("journal.txt"); + + _locations.clear(); + while (loc->pos() < loc->size()) { + Common::String line; + while ((c = loc->readByte()) != '\0') + line += c; + + _locations.push_back(line); + } + + delete loc; +} + +/** + * Loads the description for the current display index in the journal, and then + * word wraps the result to prepare it for being displayed + */ +bool Journal::loadJournalFile(bool alreadyLoaded) { + Inventory &inv = *_vm->_inventory; + People &people = *_vm->_people; + Screen &screen = *_vm->_screen; + Talk &talk = *_vm->_talk; + JournalEntry &journalEntry = _data[_index]; + Statement &statement = talk[journalEntry._statementNum]; + + Common::String dirFilename = _directory[journalEntry._converseNum]; + bool replyOnly = journalEntry._replyOnly; + Common::String locStr(dirFilename.c_str(), dirFilename.c_str() + 4); + int newLocation = atoi(locStr.c_str()); + + // If not flagged as alrady loaded, load the conversation into script variables + if (!alreadyLoaded) { + // See if the file to be used is already loaded + if (journalEntry._converseNum != _converseNum) { + // Nope. Free any previously loaded talk + talk.freeTalkVars(); + + // Find the person being talked to + talk._talkTo = -1; + for (int idx = 0; idx < MAX_PEOPLE; ++idx) { + Common::String portrait = people[idx]._portrait; + Common::String numStr(portrait.c_str(), portrait.c_str() + 4); + + if (locStr == numStr) { + talk._talkTo = idx; + break; + } + } + + // Load the talk file + talk.loadTalkFile(dirFilename); + } + } + + if (talk[0]._statement.hasPrefix("*") || talk[0]._statement.hasPrefix("^")) + replyOnly = true; + + // If this isn't the first journal entry, see if the previous journal entry + // was in the same scene to see if we need to include the scene header + int oldLocation = -1; + if (_index != 0) { + // Get the scene number of the prior journal entry + Common::String priorEntry = _directory[_data[_index - 1]._converseNum]; + oldLocation = atoi(Common::String(priorEntry.c_str() + 4, priorEntry.c_str() + 6).c_str()); + } + + // Start building journal string + Common::String journalString; + + if (newLocation != oldLocation) { + // Add in scene title + journalString = "@" + _locations[newLocation - 1] + ":"; + + // See if title can fit into a single line, or requires splitting on 2 lines + int width = screen.stringWidth(journalString.c_str() + 1); + if (width > 230) { + // Scan backwards from end of title to find a space between a word + // where the width is less than the maximum allowed for the line + const char *lineP = journalString.c_str() + journalString.size() - 1; + while (width > 230 || *lineP != ' ') + width -= screen.charWidth(*lineP--); + + // Split the header into two lines, and add a '@' prefix + // to the second line as well + journalString = Common::String(journalString.c_str(), lineP) + "\n@" + + Common::String(lineP + 1); + } + + // Add a newline at the end of the title + journalString += '\n'; + } + + // If Holmes has something to say first, then take care of it + if (!replyOnly) { + // Handle the grammar + journalString += "Holmes "; + if (talk[journalEntry._statementNum]._statement.hasSuffix("?")) + journalString += "asked "; + else + journalString += "said to "; + + switch (talk._talkTo) { + case 1: + journalString += "me"; + break; + case 2: + journalString += "the Inspector"; + break; + default: + journalString += inv._names[talk._talkTo]; + break; + } + journalString += ", \""; + + // Add the statement + journalString += statement._statement; + } + + // Handle including the reply + bool startOfReply = true; + bool ctrlSpace = false; + bool commentFlag = false; + bool commentJustPrinted = false; + const char *replyP = statement._reply.c_str(); + + while (*replyP) { + char c = *replyP; + + // Is it a control character? + if (c < 128) { + // Nope. Set flag for allowing control coes to insert spaces + ctrlSpace = true; + + // Check for embedded comments + if (c == '{' || c == '}') { + // Comment characters. If we're starting a comment and there's + // already text displayed, add a closing quote + if (c == '{' && !startOfReply && !commentJustPrinted) + journalString += '"'; + + // If a reply isn't just being started, and we didn't just end + // a comment (which would have added a line), add a carriage return + if (!startOfReply && ((!commentJustPrinted && c == '{') || c == '}')) + journalString += '"'; + + // Handle setting or clearing comment state + if (c == '{') { + commentFlag = true; + commentJustPrinted = false; + } else { + commentFlag = false; + commentJustPrinted = true; + } + } else { + if (startOfReply) { + if (!replyOnly) { + journalString += "\"\n"; + + if (talk._talkTo == 1) + journalString += "I replied, \""; + else + journalString += "The reply was, \""; + } else { + if (talk._talkTo == 1) + journalString += "I"; + else if (talk._talkTo == 2) + journalString += "The Inspector"; + else + journalString += inv._names[talk._talkTo]; + + const char *strP = replyP + 1; + char v; + do { + v = *strP++; + } while (v && v < 128 && v != '.' && v != '!' && v != '?'); + + if (v == '?') + journalString += " asked, \""; + else + journalString += " said, \""; + } + + startOfReply = false; + } + + // Copy text from the place until either the reply ends, a comment + // {} block is started, or a control character is encountered + do { + journalString += *replyP++; + } while (*replyP && *replyP < 128 && *replyP != '{' && *replyP != '}'); + + // Move pointer back, since the outer for loop will increment it again + --replyP; + commentJustPrinted = false; + } + } else if (c == 128) { + if (!startOfReply) { + if (!commentFlag && !commentJustPrinted) + journalString += "\"\n"; + + journalString += "Then "; + commentFlag = false; + } else if (!replyOnly) { + journalString += "\"\n"; + } + + startOfReply = false; + c = *++replyP; + + if ((c - 1) == 0) + journalString += "Holmes"; + else if ((c - 1) == 1) + journalString += "I"; + else if ((c - 1) == 2) + journalString += "the Inspector"; + else + journalString += inv._names[c - 1]; + + const char *strP = replyP + 1; + char v; + do { + v = *strP++; + } while (v && v < 128 && v != '.' && v != '!' && v != '?'); + + if (v == '?') + journalString += " asked, \""; + else + journalString += " said, \""; + } else { + // Control code, so move past it and any parameters + ++replyP; + switch (c) { + case 129: // Run canim + case 130: // Assign side + case 131: // Pause with control + case 136: // Pause without control + case 157: // Walk to canimation + // These commands don't have any param + break; + + case 134: // Change sequence + replyP += (replyP[0] & 127) + replyP[2] + 1; + break; + + case 135: // Walk to co-ords + case 154: // Move mouse + replyP += 3; + break; + + case 139: // Set flag + case 143: // If statement + ++replyP; + break; + + case 140: // Play voice file + case 150: // Play prologue + case 153: // Call talk file + replyP += 7; + break; + + case 141: // Toggle object + case 151: // Put item in inventory + case 152: // Set object + case 155: // Info line + case 158: // Delete item from inventory + replyP += *replyP & 127; + break; + + case 149: // Goto scene + replyP += 4; + break; + + case 161: // End of line + journalString += "\n"; + break; + + default: + break; + } + + // Put a space in the output for a control character, unless it's + // immediately coming after another control character + if (ctrlSpace && c != 130 && c != 161 && !commentJustPrinted) { + journalString += " "; + ctrlSpace = false; + } + } + } + + if (!startOfReply && !commentJustPrinted) + journalString += '"'; + + // Finally finished building the journal text. Need to process the text to + // word wrap it to fit on-screen. The resulting lines are stored in the + // _entries array + _entries.clear(); + + while (!journalString.empty()) { + const char *startP = journalString.c_str(); + + // If the first character is a '@' flagging a title line, then move + // past it, so the @ won't be included in the line width calculation + if (*startP == '@') + ++startP; + + // Build up chacters until a full line is found + int width = 0; + const char *endP = startP; + while (width < 230 && *endP && *endP != '\n' && (endP - startP) < 79) + width += screen.charWidth(*endP++); + + // If word wrapping, move back to end of prior word + if (width >= 230 || (endP - startP) >= 79) { + while (*--endP != ' ') + ; + } + + // Add in the line + _entries.push_back(Common::String(startP, endP)); + + // Strip line off from string being processed + journalString = *endP ? Common::String(endP + 1) : ""; + } + + // Add a blank line at the end of the text as long as text was present + if (!startOfReply) { + _entries.push_back(""); + } else { + _entries.clear(); + } + + return _entries.size(); +} + + } // End of namespace Sherlock diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h index 87e5a4f8f2..af8d683619 100644 --- a/engines/sherlock/journal.h +++ b/engines/sherlock/journal.h @@ -25,20 +25,44 @@ #include "common/scummsys.h" #include "common/array.h" +#include "common/str-array.h" +#include "common/stream.h" namespace Sherlock { +struct JournalEntry { + int _converseNum; + bool _replyOnly; + int _statementNum; + + JournalEntry() : _converseNum(0), _replyOnly(false), _statementNum(0) {} + JournalEntry(int converseNum, int statementNum, bool replyOnly = false) : + _converseNum(converseNum), _statementNum(statementNum), _replyOnly(replyOnly) {} +}; + +class SherlockEngine; + class Journal { -public: - Common::Array _data; +private: + SherlockEngine *_vm; + Common::Array _data; + Common::StringArray _directory; + Common::StringArray _locations; + Common::StringArray _entries; int _count; int _maxPage; int _index; int _sub; int _up, _down; int _page; + int _converseNum; + + void loadJournalLocations(); + + bool loadJournalFile(bool alreadyLoaded); +public: public: - Journal(); + Journal(SherlockEngine *vm); void record(int converseNum, int statementNum); }; diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index aa54c67567..a1fad019c8 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -82,6 +82,7 @@ public: ~People(); Person &operator[](PeopleId id) { return _data[id]; } + Person &operator[](int idx) { return _data[idx]; } bool isHolmesActive() const { return _walkLoaded && _holmesOn; } diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 04a9ed54d5..20a805594e 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -79,7 +79,7 @@ void SherlockEngine::initialize() { _debugger = new Debugger(this); _events = new Events(this); _inventory = new Inventory(this); - _journal = new Journal(); + _journal = new Journal(this); _people = new People(this); _scene = new Scene(this); _screen = new Screen(this); diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index 0cd0a8c638..48cdd2b5b2 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -90,15 +90,12 @@ private: TalkHistoryEntry _talkHistory[500]; int _speaker; int _talkIndex; - int _talkTo; int _scriptSelect; int _converseNum; int _talkStealth; int _talkToFlag; bool _moreTalkUp, _moreTalkDown; - void loadTalkFile(const Common::String &filename); - void stripVoiceCommands(); void setTalkMap(); @@ -108,11 +105,14 @@ private: public: bool _talkToAbort; int _talkCounter; + int _talkTo; public: Talk(SherlockEngine *vm); void setSequences(const byte *talkSequences, const byte *stillSequences, int maxPeople); + Statement &operator[](int idx) { return _statements[idx]; } + void talkTo(const Common::String &filename); void talk(int objNum); @@ -121,6 +121,8 @@ public: void drawInterface(); + void loadTalkFile(const Common::String &filename); + void setStillSeq(int speaker); void clearSequences(); void pullSequence(); -- cgit v1.2.3 From 86022c065c1bf7aa67549de602cd6e8933477d74 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 1 Apr 2015 23:19:00 -0400 Subject: SHERLOCK: Implemented Journal::record --- engines/sherlock/journal.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index a9eb86bf07..dcddddbbbd 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -52,10 +52,23 @@ void Journal::record(int converseNum, int statementNum) { // Record the entry into the list _data.push_back(JournalEntry(converseNum, statementNum)); + _index = _data.size() - 1; - bool newLines = loadJournalFile(true); + // Load the text for the new entry to get the number of lines it will have + int newLines = loadJournalFile(true); - // TODO + // Restore old state + _index = saveIndex; + _sub = saveSub; + + // If new lines were added to the ournal, update the total number of lines + // the journal continues + if (newLines) { + _maxPage += newLines; + } else { + // No lines in entry, so remove the new entry from the journal + _data.remove_at(_data.size() - 1); + } } void Journal::loadJournalLocations() { -- cgit v1.2.3 From 2c36889ec5312b15a7deba8a19003d9500425cb3 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 2 Apr 2015 08:11:36 -0400 Subject: SHERLOCK: Rename journal fields for clarity --- engines/sherlock/journal.cpp | 24 ++++++++++++------------ engines/sherlock/journal.h | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index dcddddbbbd..04165cd827 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -27,7 +27,7 @@ namespace Sherlock { Journal::Journal(SherlockEngine *vm): _vm(vm) { // Allow up to 1000 statements - _data.resize(1000); + _journal.resize(1000); // Initialize fields _count = 0; @@ -51,8 +51,8 @@ void Journal::record(int converseNum, int statementNum) { int saveSub = _sub; // Record the entry into the list - _data.push_back(JournalEntry(converseNum, statementNum)); - _index = _data.size() - 1; + _journal.push_back(JournalEntry(converseNum, statementNum)); + _index = _journal.size() - 1; // Load the text for the new entry to get the number of lines it will have int newLines = loadJournalFile(true); @@ -67,7 +67,7 @@ void Journal::record(int converseNum, int statementNum) { _maxPage += newLines; } else { // No lines in entry, so remove the new entry from the journal - _data.remove_at(_data.size() - 1); + _journal.remove_at(_journal.size() - 1); } } @@ -118,7 +118,7 @@ bool Journal::loadJournalFile(bool alreadyLoaded) { People &people = *_vm->_people; Screen &screen = *_vm->_screen; Talk &talk = *_vm->_talk; - JournalEntry &journalEntry = _data[_index]; + JournalEntry &journalEntry = _journal[_index]; Statement &statement = talk[journalEntry._statementNum]; Common::String dirFilename = _directory[journalEntry._converseNum]; @@ -158,7 +158,7 @@ bool Journal::loadJournalFile(bool alreadyLoaded) { int oldLocation = -1; if (_index != 0) { // Get the scene number of the prior journal entry - Common::String priorEntry = _directory[_data[_index - 1]._converseNum]; + Common::String priorEntry = _directory[_journal[_index - 1]._converseNum]; oldLocation = atoi(Common::String(priorEntry.c_str() + 4, priorEntry.c_str() + 6).c_str()); } @@ -390,8 +390,8 @@ bool Journal::loadJournalFile(bool alreadyLoaded) { // Finally finished building the journal text. Need to process the text to // word wrap it to fit on-screen. The resulting lines are stored in the - // _entries array - _entries.clear(); + // _lines array + _lines.clear(); while (!journalString.empty()) { const char *startP = journalString.c_str(); @@ -414,7 +414,7 @@ bool Journal::loadJournalFile(bool alreadyLoaded) { } // Add in the line - _entries.push_back(Common::String(startP, endP)); + _lines.push_back(Common::String(startP, endP)); // Strip line off from string being processed journalString = *endP ? Common::String(endP + 1) : ""; @@ -422,12 +422,12 @@ bool Journal::loadJournalFile(bool alreadyLoaded) { // Add a blank line at the end of the text as long as text was present if (!startOfReply) { - _entries.push_back(""); + _lines.push_back(""); } else { - _entries.clear(); + _lines.clear(); } - return _entries.size(); + return _lines.size(); } diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h index af8d683619..4add81d508 100644 --- a/engines/sherlock/journal.h +++ b/engines/sherlock/journal.h @@ -45,10 +45,10 @@ class SherlockEngine; class Journal { private: SherlockEngine *_vm; - Common::Array _data; + Common::Array _journal; Common::StringArray _directory; Common::StringArray _locations; - Common::StringArray _entries; + Common::StringArray _lines; int _count; int _maxPage; int _index; -- cgit v1.2.3 From 8ee021434236b454faf52995fb102322f2e7bd8f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 2 Apr 2015 08:44:07 -0400 Subject: SHERLOCK: Implemented Inventory::highlight --- engines/sherlock/inventory.cpp | 15 +++++++++++++-- engines/sherlock/inventory.h | 2 +- engines/sherlock/user_interface.cpp | 4 ++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index ac37e7c587..f7706c9d64 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -329,8 +329,19 @@ void Inventory::invCommands(bool slamIt) { } } -void Inventory::doInvLite(int index, byte color) { - // TODO +/** + * Set the highlighting color of a given inventory item + */ +void Inventory::highlight(int index, byte color) { + Screen &screen = *_vm->_screen; + Surface &bb = *screen._backBuffer; + int slot = index - _invIndex; + Graphics::Surface &img = (*_invShapes[slot])[0]._frame; + + bb.fillRect(Common::Rect(8 + slot * 52, 165, (slot + 1) * 52, 194), color); + bb.transBlitFrom(img, Common::Point(6 + slot * 52 + ((47 - img.w) / 2), + 163 + ((33 - img.h) / 2))); + screen.slamArea(8 + slot * 52, 165, 44, 30); } void Inventory::doInvJF() { diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index 3c01dc38da..55abc4c960 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -87,7 +87,7 @@ public: void invCommands(bool slamIt); - void doInvLite(int index, byte color); + void highlight(int index, byte color); void doInvJF(); }; diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 74142ab80e..6f60049e31 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -789,11 +789,11 @@ void UserInterface::doInvControl() { if (_oldSelector != -1) { // Un-highlight if (_oldSelector >= inv._invIndex && _oldSelector < (inv._invIndex + 6)) - inv.doInvLite(_oldSelector, BUTTON_MIDDLE); + inv.highlight(_oldSelector, BUTTON_MIDDLE); } if (_selector != -1) - inv.doInvLite(_selector, 235); + inv.highlight(_selector, 235); _oldSelector = _selector; } -- cgit v1.2.3 From 9c24ae75909088742aae7b303f80de43cb31a7a6 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 2 Apr 2015 18:30:16 -0400 Subject: SHERLOCK: Implemented Journal::drawInterface --- engines/sherlock/journal.cpp | 81 +++++++++++++++++++++++++++++++++++++ engines/sherlock/journal.h | 6 +++ engines/sherlock/user_interface.cpp | 4 ++ 3 files changed, 91 insertions(+) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 04165cd827..94c6cf69e7 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -25,6 +25,23 @@ namespace Sherlock { +#define JOURNAL_BUTTONS_Y 178 + +// Positioning of buttons in the journal view +const int JOURNAL_POINTS[9][3] = { + { 6, 68, 37 }, + { 69, 131, 100 }, + { 132, 192, 162 }, + { 193, 250, 221 }, + { 251, 313, 281 }, + { 6, 82, 44 }, + { 83, 159, 121 }, + { 160, 236, 198 }, + { 237, 313, 275 } +}; + +/*----------------------------------------------------------------*/ + Journal::Journal(SherlockEngine *vm): _vm(vm) { // Allow up to 1000 statements _journal.resize(1000); @@ -430,5 +447,69 @@ bool Journal::loadJournalFile(bool alreadyLoaded) { return _lines.size(); } +void Journal::drawInterface() { + Resources &res = *_vm->_res; + Screen &screen = *_vm->_screen; + byte palette[PALETTE_SIZE]; + + // Load in the journal background + Common::SeekableReadStream *bg = res.load("journal.lbv"); + bg->read(screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCREEN_HEIGHT); + bg->read(palette, PALETTE_SIZE); + delete bg; + + // Set the palette and print the title + screen.setPalette(palette); + screen.gPrint(Common::Point(111, 18), BUTTON_BOTTOM, "Watson's Journal"); + screen.gPrint(Common::Point(110, 17), INV_FOREGROUND, "Watson's Journal"); + + // Draw the buttons + screen.makeButton(Common::Rect(JOURNAL_POINTS[0][0], JOURNAL_BUTTONS_Y, + JOURNAL_POINTS[0][1], JOURNAL_BUTTONS_Y + 10), + JOURNAL_POINTS[0][2] - screen.stringWidth("Exit") / 2, "Exit"); + screen.makeButton(Common::Rect(JOURNAL_POINTS[1][0], JOURNAL_BUTTONS_Y, + JOURNAL_POINTS[1][1], JOURNAL_BUTTONS_Y + 10), + JOURNAL_POINTS[1][2] - screen.stringWidth("Back 10") / 2, "Back 10"); + screen.makeButton(Common::Rect(JOURNAL_POINTS[2][0], JOURNAL_BUTTONS_Y, + JOURNAL_POINTS[2][1], JOURNAL_BUTTONS_Y + 10), + JOURNAL_POINTS[2][2] - screen.stringWidth("Up") / 2, "Up"); + screen.makeButton(Common::Rect(JOURNAL_POINTS[3][0], JOURNAL_BUTTONS_Y, + JOURNAL_POINTS[3][1], JOURNAL_BUTTONS_Y + 10), + JOURNAL_POINTS[3][2] - screen.stringWidth("Down") / 2, "Down"); + screen.makeButton(Common::Rect(JOURNAL_POINTS[4][0], JOURNAL_BUTTONS_Y, + JOURNAL_POINTS[4][1], JOURNAL_BUTTONS_Y + 10), + JOURNAL_POINTS[4][2] - screen.stringWidth("Ahead 10") / 2, "Ahead 10"); + screen.makeButton(Common::Rect(JOURNAL_POINTS[5][0], JOURNAL_BUTTONS_Y + 11, + JOURNAL_POINTS[5][1], JOURNAL_BUTTONS_Y + 21), + JOURNAL_POINTS[5][2] - screen.stringWidth("Search") / 2, "Search"); + screen.makeButton(Common::Rect(JOURNAL_POINTS[6][0], JOURNAL_BUTTONS_Y + 11, + JOURNAL_POINTS[6][1], JOURNAL_BUTTONS_Y + 21), + JOURNAL_POINTS[6][2] - screen.stringWidth("First Page") / 2, "First Page"); + screen.makeButton(Common::Rect(JOURNAL_POINTS[7][0], JOURNAL_BUTTONS_Y + 11, + JOURNAL_POINTS[7][1], JOURNAL_BUTTONS_Y + 21), + JOURNAL_POINTS[7][2] - screen.stringWidth("Last Page") / 2, "Last Page"); + screen.makeButton(Common::Rect(JOURNAL_POINTS[8][0], JOURNAL_BUTTONS_Y + 11, + JOURNAL_POINTS[8][1], JOURNAL_BUTTONS_Y + 21), + JOURNAL_POINTS[8][2] - screen.stringWidth("Print Text") / 2, "Print Text"); + + if (_journal.size() == 0) { + _up = _down = 0; + } else { + doJournal(0, 0); + } + + doArrows(); + + // Show the entire screen + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); +} + +void Journal::doArrows() { + // TODO +} + +void Journal::doJournal(int direction, int howFar) { + // TODO +} } // End of namespace Sherlock diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h index 4add81d508..34d99af0ec 100644 --- a/engines/sherlock/journal.h +++ b/engines/sherlock/journal.h @@ -60,11 +60,17 @@ private: void loadJournalLocations(); bool loadJournalFile(bool alreadyLoaded); + + void doArrows(); + + void doJournal(int direction, int howFar); public: public: Journal(SherlockEngine *vm); void record(int converseNum, int statementNum); + + void drawInterface(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 6f60049e31..01b08ffd71 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1127,6 +1127,10 @@ void UserInterface::doTalkControl() { } void UserInterface::journalControl() { + Journal &journal = *_vm->_journal; + + journal.drawInterface(); + // TODO } -- cgit v1.2.3 From 91774a0aebb0b37010627e448a1ac18169cec07f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 2 Apr 2015 19:19:36 -0400 Subject: SHERLOCK: Implemented Journal::doButtons --- engines/sherlock/journal.cpp | 24 ++++++++++++++++++++++-- engines/sherlock/journal.h | 2 +- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 94c6cf69e7..b45d772716 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -51,7 +51,7 @@ Journal::Journal(SherlockEngine *vm): _vm(vm) { _maxPage = 0; _index = 0; _sub = 0; - _up = _down = 0; + _up = _down = false; _page = 0; _converseNum = -1; @@ -504,8 +504,28 @@ void Journal::drawInterface() { screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } +/** + * Display the arrows that can be used to scroll up and down pages + */ void Journal::doArrows() { - // TODO + Screen &screen = *_vm->_screen; + byte color; + + color = (_page > 1) ? COMMAND_FOREGROUND : COMMAND_NULL; + screen.buttonPrint(Common::Point(JOURNAL_POINTS[1][2], JOURNAL_BUTTONS_Y), color, false, "Back 10"); + screen.buttonPrint(Common::Point(JOURNAL_POINTS[2][2], JOURNAL_BUTTONS_Y), color, false, "Up"); + + color = _down ? COMMAND_FOREGROUND : COMMAND_NULL; + screen.buttonPrint(Common::Point(JOURNAL_POINTS[3][2], JOURNAL_BUTTONS_Y), color, false, "Down"); + screen.buttonPrint(Common::Point(JOURNAL_POINTS[4][2], JOURNAL_BUTTONS_Y), color, false, "Ahead 10"); + screen.buttonPrint(Common::Point(JOURNAL_POINTS[7][2], JOURNAL_BUTTONS_Y + 11), color, false, "Last Page"); + + color = _journal.size() > 0 ? COMMAND_FOREGROUND : COMMAND_NULL; + screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), color, false, "Search"); + screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11), color, false, "Print Text"); + + color = _page > 1 ? COMMAND_FOREGROUND : COMMAND_NULL; + screen.buttonPrint(Common::Point(JOURNAL_POINTS[6][2], JOURNAL_BUTTONS_Y + 11), color, false, "First Page"); } void Journal::doJournal(int direction, int howFar) { diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h index 34d99af0ec..8ad19dc0e5 100644 --- a/engines/sherlock/journal.h +++ b/engines/sherlock/journal.h @@ -53,7 +53,7 @@ private: int _maxPage; int _index; int _sub; - int _up, _down; + bool _up, _down; int _page; int _converseNum; -- cgit v1.2.3 From 402846aea5e08d774521caaa9bd29531c738a100 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 4 Apr 2015 08:54:19 -0500 Subject: SHERLOCK: Implemented doJournal --- engines/sherlock/journal.cpp | 259 ++++++++++++++++++++++++++++++++++++++++++- engines/sherlock/journal.h | 5 +- engines/sherlock/screen.h | 3 +- 3 files changed, 263 insertions(+), 4 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index b45d772716..140b766dca 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -26,6 +26,7 @@ namespace Sherlock { #define JOURNAL_BUTTONS_Y 178 +#define LINES_PER_PAGE 11 // Positioning of buttons in the journal view const int JOURNAL_POINTS[9][3] = { @@ -528,8 +529,262 @@ void Journal::doArrows() { screen.buttonPrint(Common::Point(JOURNAL_POINTS[6][2], JOURNAL_BUTTONS_Y + 11), color, false, "First Page"); } -void Journal::doJournal(int direction, int howFar) { - // TODO +/** + * Displays a page of the journal at the current index + */ +bool Journal::doJournal(int direction, int howFar) { + Events &events = *_vm->_events; + Screen &screen = *_vm->_screen; + int yp = 37; + int startPage = _page; + bool endJournal = false; + bool firstOccurance = false; + bool searchSuccessful = false; + bool endFlag = false; + int lineNum = 0; + int maxLines; + int savedIndex; + int savedSub; + int temp; + bool inc; + const char *matchP; + int width; + + _converseNum = -1; + _down = true; + + do { + // Get the number of lines for the current journal entry + maxLines = loadJournalFile(false); + if (!maxLines) { + // Entry has no text, so it must be a stealth eny. Move onto further journal entries + // until an entry with text is found + if (++_index == (int)_journal.size()) { + endJournal = true; + } else { + _sub = 0; + maxLines = loadJournalFile(false); + } + } + } while (!endJournal && !maxLines); + + // Check if there no further pages with text until the end of the journal + if (endJournal) { + // If moving forward or backwards, clear the page before printing + if (direction) + clearPage(); + + screen.gPrint(Common::Point(235, 21), PEN_COLOR, "Page %d", _page); + return false; + } + + // If the journal page is being changed, set the wait cursor + if (direction) + events.setCursor(WAIT); + + switch (direction) { + case 1: + case 4: + // Move backwards howFar number of lines unless either the start of the journal is reached, + // or a searched for keyword is found + do { + // Animate the glass mouse cursor + int cursorNum = (int)events.getCursor() + 1; + if (cursorNum > (WAIT + 2)) + cursorNum = WAIT; + events.setCursor((CursorId)cursorNum); + + // Move backwards through the journal file a line at a time + if (--_sub < 0) { + do { + if (--_index < 0) { + _index = 0; + _sub = 0; + endJournal = true; + } + else { + maxLines = loadJournalFile(false); + _sub = maxLines - 1; + } + } while (!endJournal && !maxLines); + } + + // If it's search mode, check each line for the given keyword + if (direction >= 3 && maxLines && !endJournal && !searchSuccessful) { + Common::String line = _lines[_sub]; + line.toUppercase(); + if (strstr(line.c_str(), _find.c_str()) != nullptr) { + // Found a match. Reset howFar so that the start of page that the match + // was found on will be displayed + searchSuccessful = true; + howFar = ((lineNum / LINES_PER_PAGE) + 1) * LINES_PER_PAGE; + } + } + + ++lineNum; + } while (lineNum < howFar && !endJournal); + + if (!_index && !_sub) + _page = 1; + else + _page -= howFar / LINES_PER_PAGE; + break; + + case 2: + case 3: + // Move howFar lines ahead unless the end of the journal is reached, + // or a searched for keyword is found + for (temp = 0; (temp < (howFar / LINES_PER_PAGE)) && !endJournal && !searchSuccessful; ++temp) { + // Handle animating mouse cursor + int cursorNum = (int)events.getCursor() + 1; + if (cursorNum >(WAIT + 2)) + cursorNum = WAIT; + events.setCursor((CursorId)cursorNum); + + lineNum = 0; + savedIndex = _index; + savedSub = _sub; + + // Move a single page ahead + do { + // If in search mode, check for keyword + if (direction >= 3 && _page != startPage) { + Common::String line = _lines[_sub]; + line.toUppercase(); + if (strstr(line.c_str(), _find.c_str()) != nullptr) + searchSuccessful = true; + } + + // Move forwards a line at a time, unless search word was found + if (!searchSuccessful) { + if (++_sub == maxLines) { + // Reached end of page + do { + if (++_index == (int)_lines.size()) { + _index = savedIndex; + _sub = savedSub; + maxLines = loadJournalFile(false); + endJournal = true; + } else { + _sub = 0; + maxLines = loadJournalFile(false); + } + } while (!endJournal && !maxLines); + } + + ++lineNum; + } + } while ((lineNum < LINES_PER_PAGE) && !endJournal && !searchSuccessful); + + if (!endJournal && !searchSuccessful) + // Move to next page + ++_page; + + if (searchSuccessful) { + // Search found, so show top of the page it was found on + _index = savedIndex; + _sub = savedSub; + maxLines = loadJournalFile(false); + } + } + break; + + default: + break; + } + + if (direction) { + events.setCursor(ARROW); + clearPage(); + } + + screen.gPrint(Common::Point(235, 21), PEN_COLOR, "Page %d", _page); + + temp = _sub; + savedIndex = _index; + lineNum = 0; + + do { + inc = true; + + // If there wasn't any line to print at the top of the page, we won't need to + // increment the y position + if (_lines[temp].empty() && yp == 37) + inc = false; + + // If there's a searched for keyword in the line, it will need to be highlighted + if (searchSuccessful && firstOccurance) { + // Check if line has the keyword + Common::String line = _lines[temp]; + line.toUppercase(); + if ((matchP = strstr(line.c_str(), _find.c_str())) != nullptr) { + matchP = _lines[temp].c_str() + (matchP - line.c_str()); + firstOccurance = false; + + // Print out the start of the line before the matching keyword + Common::String lineStart(_lines[temp].c_str(), matchP); + if (lineStart.hasPrefix("@")) { + width = screen.stringWidth(lineStart.c_str() + 1); + screen.gPrint(Common::Point(53, yp), 15, "%s", lineStart.c_str() + 1); + } else { + width = screen.stringWidth(lineStart.c_str()); + screen.gPrint(Common::Point(53, yp), PEN_COLOR, lineStart.c_str()); + } + + // Print out the found keyword + Common::String lineMatch(matchP, matchP + _find.size()); + screen.gPrint(Common::Point(53 + width, yp), INV_FOREGROUND, lineMatch.c_str()); + width += screen.stringWidth(lineMatch.c_str()); + + // Print remainder of line + screen.gPrint(Common::Point(53 + width, yp), PEN_COLOR, matchP + _find.size()); + } else if (_lines[temp].hasPrefix("@")) { + screen.gPrint(Common::Point(53, yp), 15, _lines[temp].c_str() + 1); + } else { + screen.gPrint(Common::Point(53, yp), PEN_COLOR, _lines[temp].c_str()); + } + } else { + if (_lines[temp].hasPrefix("@")) { + screen.gPrint(Common::Point(53, yp), 15, _lines[temp].c_str() + 1); + } else { + screen.gPrint(Common::Point(53, yp), PEN_COLOR, _lines[temp].c_str()); + } + } + + if (++temp == maxLines) { + // Move to next page + do { + if (_index < (_journal.size() - 1) && lineNum < (LINES_PER_PAGE - 1)) { + ++_index; + maxLines = loadJournalFile(false); + temp = 0; + } else { + if (_index == (_journal.size() - 1)) + _down = false; + endFlag = true; + } + } while (!endFlag && !maxLines); + } + + if (inc) { + // Move to next line + ++lineNum; + yp += 13; + } + } while (lineNum < LINES_PER_PAGE && !endFlag); + + _index = savedIndex; + _up = _index || _sub; + + return direction >= 3 && searchSuccessful; +} + +/** + * Clears the journal page + */ +void Journal::clearPage() { + // Clear the journal page by redrawing it from scratch + drawInterface(); } } // End of namespace Sherlock diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h index 8ad19dc0e5..25f70b0e29 100644 --- a/engines/sherlock/journal.h +++ b/engines/sherlock/journal.h @@ -56,6 +56,7 @@ private: bool _up, _down; int _page; int _converseNum; + Common::String _find; void loadJournalLocations(); @@ -63,7 +64,9 @@ private: void doArrows(); - void doJournal(int direction, int howFar); + bool doJournal(int direction, int howFar); + + void clearPage(); public: public: Journal(SherlockEngine *vm); diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index edc0136471..4e37a7787c 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -50,7 +50,8 @@ enum { BUTTON_MIDDLE = 244, BUTTON_BOTTOM = 248, TALK_FOREGROUND = 12, - TALK_NULL = 16 + TALK_NULL = 16, + PEN_COLOR = 250 }; class SherlockEngine; -- cgit v1.2.3 From 005438570492b88a152a7a11e6d4df45687ba0bd Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 4 Apr 2015 17:09:59 -0500 Subject: SHERLOCK: Implement journal event handling --- engines/sherlock/journal.cpp | 392 +++++++++++++++++++++++++++++++++++- engines/sherlock/journal.h | 5 +- engines/sherlock/scene.h | 4 +- engines/sherlock/user_interface.cpp | 43 +++- 4 files changed, 438 insertions(+), 6 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 140b766dca..b05cc03372 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -41,6 +41,12 @@ const int JOURNAL_POINTS[9][3] = { { 237, 313, 275 } }; +const int SEARCH_POINTS[3][3] = { + { 51, 123, 86 }, + { 124, 196, 159 }, + { 197, 269, 232 } +}; + /*----------------------------------------------------------------*/ Journal::Journal(SherlockEngine *vm): _vm(vm) { @@ -754,12 +760,12 @@ bool Journal::doJournal(int direction, int howFar) { if (++temp == maxLines) { // Move to next page do { - if (_index < (_journal.size() - 1) && lineNum < (LINES_PER_PAGE - 1)) { + if (_index < ((int)_journal.size() - 1) && lineNum < (LINES_PER_PAGE - 1)) { ++_index; maxLines = loadJournalFile(false); temp = 0; } else { - if (_index == (_journal.size() - 1)) + if (_index == ((int)_journal.size() - 1)) _down = false; endFlag = true; } @@ -787,4 +793,386 @@ void Journal::clearPage() { drawInterface(); } +/** + * Handle events whilst the journal is being displayed + */ +bool Journal::handleEvents(int key) { + Events &events = *_vm->_events; + Screen &screen = *_vm->_screen; + bool doneFlag = false; + Common::Point pt = events.mousePos(); + byte color; + enum Button { + BTN_NONE, BTN_EXIT, BTN_BACK10, BTN_UP, BTN_DOWN, BTN_AHEAD110, BTN_SEARCH, + BTN_FIRST_PAGE, BTN_LAST_PAGE, BTN_PRINT_TEXT + }; + Button found = BTN_NONE; + + if (events._pressed || events._released) { + // Exit button + if (pt.x > JOURNAL_POINTS[0][0] && pt.x < JOURNAL_POINTS[0][1] && pt.y >= JOURNAL_BUTTONS_Y && + pt.y < (JOURNAL_BUTTONS_Y + 10)) { + found = BTN_EXIT; + color = COMMAND_HIGHLIGHTED; + } else { + color = COMMAND_FOREGROUND; + } + screen.buttonPrint(Common::Point(JOURNAL_POINTS[1][2], JOURNAL_BUTTONS_Y), color, true, "Exit"); + + // Back 10 button + if (pt.x > JOURNAL_POINTS[1][0] && pt.x < JOURNAL_POINTS[1][1] && pt.y >= JOURNAL_BUTTONS_Y && + pt.y < (JOURNAL_BUTTONS_Y + 10) && _page > 1) { + found = BTN_BACK10; + screen.buttonPrint(Common::Point(JOURNAL_POINTS[1][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, "Back 10"); + } else if (_page > 1) { + screen.buttonPrint(Common::Point(JOURNAL_POINTS[1][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, "Back 10"); + } + + // Up button + if (pt.x > JOURNAL_POINTS[2][0] && pt.x < JOURNAL_POINTS[2][1] && pt.y >= JOURNAL_BUTTONS_Y && + pt.y < (JOURNAL_BUTTONS_Y + 10) && _up) { + found = BTN_UP; + screen.buttonPrint(Common::Point(JOURNAL_POINTS[2][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, "Up"); + } else if (_up) { + screen.buttonPrint(Common::Point(JOURNAL_POINTS[2][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, "Up"); + } + + // Down button + if (pt.x > JOURNAL_POINTS[3][0] && pt.x < JOURNAL_POINTS[3][1] && pt.y >= JOURNAL_BUTTONS_Y && + pt.y < (JOURNAL_BUTTONS_Y + 10) && _down) { + found = BTN_DOWN; + screen.buttonPrint(Common::Point(JOURNAL_POINTS[3][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, "Down"); + } else if (_down) { + screen.buttonPrint(Common::Point(JOURNAL_POINTS[3][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, "Down"); + } + + // Ahead 10 button + if (pt.x > JOURNAL_POINTS[4][0] && pt.x < JOURNAL_POINTS[4][1] && pt.y >= JOURNAL_BUTTONS_Y && + pt.y < (JOURNAL_BUTTONS_Y + 10) && _down) { + found = BTN_AHEAD110; + screen.buttonPrint(Common::Point(JOURNAL_POINTS[4][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, "Ahead 10"); + } else if (_down) { + screen.buttonPrint(Common::Point(JOURNAL_POINTS[4][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, "Ahead 10"); + } + + // Search button + if (pt.x > JOURNAL_POINTS[5][0] && pt.x < JOURNAL_POINTS[5][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) && + pt.y < (JOURNAL_BUTTONS_Y + 20) && !_journal.empty()) { + found = BTN_SEARCH; + color = COMMAND_HIGHLIGHTED; + } else if (_journal.empty()) { + color = COMMAND_NULL; + } else { + color = COMMAND_FOREGROUND; + } + screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), color, true, "Search"); + + // First Page button + if (pt.x > JOURNAL_POINTS[6][0] && pt.x < JOURNAL_POINTS[6][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) && + pt.y < (JOURNAL_BUTTONS_Y + 20) && _up) { + found = BTN_FIRST_PAGE; + color = COMMAND_HIGHLIGHTED; + } else if (_up) { + color = COMMAND_FOREGROUND; + } else { + color = COMMAND_NULL; + } + screen.buttonPrint(Common::Point(JOURNAL_POINTS[6][2], JOURNAL_BUTTONS_Y + 11), color, true, "First Page"); + + // Last Page button + if (pt.x > JOURNAL_POINTS[7][0] && pt.x < JOURNAL_POINTS[7][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) && + pt.y < (JOURNAL_BUTTONS_Y + 20) && _down) { + found = BTN_LAST_PAGE; + color = COMMAND_HIGHLIGHTED; + } else if (_down) { + color = COMMAND_FOREGROUND; + } else { + color = COMMAND_NULL; + } + screen.buttonPrint(Common::Point(JOURNAL_POINTS[7][2], JOURNAL_BUTTONS_Y + 11), color, true, "Last Page"); + + + // Print Text button + if (pt.x > JOURNAL_POINTS[8][0] && pt.x < JOURNAL_POINTS[8][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) && + pt.y < (JOURNAL_BUTTONS_Y + 20) && !_journal.empty()) { + found = BTN_PRINT_TEXT; + color = COMMAND_HIGHLIGHTED; + } else if (_journal.empty()) { + color = COMMAND_NULL; + } else { + color = COMMAND_FOREGROUND; + } + screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11), color, true, "Print Text"); + } + + if (found == BTN_EXIT && events._released) + // Exit button pressed + doneFlag = true; + + if (((found == BTN_BACK10 && events._released) || key == 'B') && (_page > 1)) { + // Scrolll up 10 pages + if (_page < 11) + doJournal(1, (_page - 1) * LINES_PER_PAGE); + else + doJournal(1, 10 * LINES_PER_PAGE); + + doArrows(); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + } + + if (((found == BTN_UP && events._released) || key =='U') && _up) { + // Scroll up + doJournal(1, LINES_PER_PAGE); + doArrows(); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + } + + if (((found == BTN_DOWN && events._released) || key =='D') && _down) { + // Scroll down + doJournal(2, LINES_PER_PAGE); + doArrows(); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + } + + if (((found == BTN_AHEAD110 && events._released) || key == 'A') && _down) { + // Scroll down 10 pages + if ((_page + 10) > _maxPage) + doJournal(2, (_maxPage - _page) * LINES_PER_PAGE); + else + doJournal(2, 10 * LINES_PER_PAGE); + + doArrows(); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + } + + if (((found == BTN_SEARCH && events._released) || key == 'S') && !_journal.empty()) { + screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), COMMAND_FOREGROUND, true, "Search"); + bool notFound = false; + + int dir; + + do { + if ((dir = getFindName(notFound)) != 0) { + int savedIndex = _index; + int savedSub = _sub; + int savedPage = _page; + + if (doJournal(dir + 2, 1000 * LINES_PER_PAGE) == 0) { + _index = savedIndex; + _sub = savedSub; + _page = savedPage; + + clearPage(); + doJournal(0, 0); + notFound = true; + } else { + doneFlag = true; + } + + doArrows(); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + } else { + doneFlag = true; + } + } while (!doneFlag); + doneFlag = false; + } + + if (((found == BTN_FIRST_PAGE && events._released) || key == 'F') && _up) { + // First page + _index = _sub = 0; + _up = _down = false; + _page = 1; + + clearPage(); + doJournal(0, 0); + doArrows(); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + } + + if (((found == BTN_LAST_PAGE && events._released) || key == 'L') && _down) { + // Last page + if ((_page + 10) > _maxPage) + doJournal(2, (_maxPage - _page) * LINES_PER_PAGE); + else + doJournal(2, 1000 * LINES_PER_PAGE); + + doArrows(); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + } + + events.wait(2); + + return doneFlag; +} + +/** + * Show the search submenu + */ +int Journal::getFindName(bool printError) { + Events &events = *_vm->_events; + Screen &screen = *_vm->_screen; + Talk &talk = *_vm->_talk; + int xp; + int yp = 174; + bool flag = false; + Common::String name; + enum Button { BTN_NONE, BTN_EXIT, BTN_BACKWARD, BTN_FORWARD }; + Button found = BTN_NONE; + int done = 0; + byte color; + + // Draw search panel + screen.makePanel(Common::Rect(6, 171, 313, 199)); + screen.makeButton(Common::Rect(SEARCH_POINTS[0][0], yp, SEARCH_POINTS[0][1], yp + 10), + SEARCH_POINTS[0][2] - screen.stringWidth("Exit") / 2, "Exit"); + screen.makeButton(Common::Rect(SEARCH_POINTS[1][0], yp, SEARCH_POINTS[1][1], yp + 10), + SEARCH_POINTS[1][2] - screen.stringWidth("Backward") / 2, "Backward"); + screen.makeButton(Common::Rect(SEARCH_POINTS[2][0], yp, SEARCH_POINTS[2][1], yp + 10), + SEARCH_POINTS[2][2] - screen.stringWidth("Forward") / 2, "Forward"); + + screen.gPrint(Common::Point(SEARCH_POINTS[0][2] - screen.stringWidth("Exit") / 2, yp), COMMAND_FOREGROUND, "E"); + screen.gPrint(Common::Point(SEARCH_POINTS[1][2] - screen.stringWidth("Backward") / 2, yp), COMMAND_FOREGROUND, "B"); + screen.gPrint(Common::Point(SEARCH_POINTS[2][2] - screen.stringWidth("Forward") / 2, yp), COMMAND_FOREGROUND, "F"); + + screen.fillRect(Common::Rect(12, 185, 307, 186), BUTTON_BOTTOM); + screen.vLine(12, 185, 195, BUTTON_BOTTOM); + screen.hLine(13, 195, 306, BUTTON_TOP); + screen.hLine(306, 186, 195, BUTTON_TOP); + + if (printError) { + screen.gPrint(Common::Point((SHERLOCK_SCREEN_WIDTH - screen.stringWidth("Text Not Found !")) / 2, 185), + INV_FOREGROUND, "Text Not Found !"); + } else if (!_find.empty()) { + // There's already a search term, display it already + screen.gPrint(Common::Point(15, 185), TALK_FOREGROUND, _find.c_str()); + name = _find; + } + + screen.slamArea(6, 171, 307, 28); + + if (printError) { + // Give time for user to see the message + for (int idx = 0; idx < 40 && !_vm->shouldQuit() && !events.kbHit() && !events._released; ++idx) { + events.pollEvents(); + events.setButtonState(); + + events.wait(2); + } + + events.clearKeyboard(); + screen.fillRect(Common::Rect(13, 186, 306, 195), BUTTON_MIDDLE); + + if (!_find.empty()) { + screen.gPrint(Common::Point(15, 185), TALK_FOREGROUND, _find.c_str()); + name = _find; + } + + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + } + + xp = 15 + screen.stringWidth(name); + yp = 186; + + do { + events._released = false; + found = BTN_NONE; + + while (!_vm->shouldQuit() && !events.kbHit() && !events._released) { + found = BTN_NONE; + if (talk._talkToAbort) + return 0; + + // Check if key or mouse button press has occurred + events.setButtonState(); + Common::Point pt = events.mousePos(); + + flag = !flag; + screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), flag ? INV_FOREGROUND : BUTTON_MIDDLE); + + if (events._pressed || events._released) { + if (pt.x > SEARCH_POINTS[0][0] && pt.x < SEARCH_POINTS[0][1] && pt.y > 174 && pt.y < 183) { + found = BTN_EXIT; + color = COMMAND_HIGHLIGHTED; + } else { + color = COMMAND_FOREGROUND; + } + screen.print(Common::Point(SEARCH_POINTS[0][2] - screen.stringWidth("Exit") / 2, 175), color, "Exit"); + + if (pt.x > SEARCH_POINTS[1][0] && pt.x < SEARCH_POINTS[1][1] && pt.y > 174 && pt.y < 183) { + found = BTN_BACKWARD; + color = COMMAND_HIGHLIGHTED; + } else { + color = COMMAND_FOREGROUND; + } + screen.print(Common::Point(SEARCH_POINTS[1][2] - screen.stringWidth("Backward") / 2, 175), color, "Backward"); + + if (pt.x > SEARCH_POINTS[2][0] && pt.x < SEARCH_POINTS[2][1] && pt.y > 174 && pt.y < 183) { + found = BTN_FORWARD; + color = COMMAND_HIGHLIGHTED; + } else { + color = COMMAND_FOREGROUND; + } + screen.print(Common::Point(SEARCH_POINTS[1][2] - screen.stringWidth("Forward") / 2, 175), color, "Forward"); + } + + events.wait(2); + } + + if (events.kbHit()) { + Common::KeyState keyState = events.getKey(); + + if (keyState.keycode == Common::KEYCODE_BACKSPACE && name.c_str() > 0) { + screen.vgaBar(Common::Rect(xp - screen.charWidth(name.lastChar()), yp, xp + 8, yp + 9), BUTTON_MIDDLE); + xp -= screen.charWidth(name.lastChar()); + screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), INV_FOREGROUND); + name.deleteLastChar(); + } + + if (keyState.keycode == Common::KEYCODE_RETURN) + done = 1; + + if (keyState.keycode == Common::KEYCODE_ESCAPE) { + screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), BUTTON_MIDDLE); + done = -1; + } + + if (keyState.keycode >= Common::KEYCODE_SPACE && keyState.keycode <= Common::KEYCODE_z + && keyState.keycode != Common::KEYCODE_AT && name.size() < 50 + && (xp + screen.charWidth(keyState.keycode)) < 296) { + screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), BUTTON_MIDDLE); + screen.print(Common::Point(xp, yp), TALK_FOREGROUND, "%c", (char)keyState.keycode); + xp += screen.charWidth((char)keyState.keycode); + name += (char)keyState.keycode; + } + } + + if (events._released) { + switch (found) { + case BTN_EXIT: + done = -1; break; + case BTN_BACKWARD: + done = 2; break; + case BTN_FORWARD: + done = 1; break; + default: + break; + } + } + } while (!done); + + if (done != -1) { + _find = name; + } else { + done = 0; + } + + // Redisplay the journal screen + clearPage(); + doJournal(0, 0); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + + return done; +} + } // End of namespace Sherlock diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h index 25f70b0e29..a5fe1e8d94 100644 --- a/engines/sherlock/journal.h +++ b/engines/sherlock/journal.h @@ -67,13 +67,16 @@ private: bool doJournal(int direction, int howFar); void clearPage(); -public: + + int getFindName(bool printError); public: Journal(SherlockEngine *vm); void record(int converseNum, int statementNum); void drawInterface(); + + bool handleEvents(int key); }; } // End of namespace Sherlock diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index cd64073621..3549325e8e 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -97,8 +97,6 @@ private: void transitionToScene(); - void updateBackground(); - void checkBgShapes(ImageFrame *frame, const Common::Point &pt); void saveSceneStatus(); @@ -167,6 +165,8 @@ public: int whichZone(const Common::Point &pt); int closestZone(const Common::Point &pt); + + void updateBackground(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 01b08ffd71..289bff814f 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1127,10 +1127,51 @@ void UserInterface::doTalkControl() { } void UserInterface::journalControl() { + Events &events = *_vm->_events; Journal &journal = *_vm->_journal; - + Scene &scene = *_vm->_scene; + Screen &screen = *_vm->_screen; + int found; + bool doneFlag = false; + + // Draw the journal screen journal.drawInterface(); + // Handle journal events + do { + found = _key = -1; + events.setButtonState(); + + // Handle keypresses + if (events.kbHit()) { + Common::KeyState keyState = events.getKey(); + if (keyState.keycode == Common::KEYCODE_x && (keyState.flags & Common::KBD_ALT)) { + _vm->quitGame(); + return; + } else if (keyState.keycode == Common::KEYCODE_e || keyState.keycode == Common::KEYCODE_ESCAPE) { + doneFlag = true; + } else { + _key = toupper(keyState.keycode); + } + } + + if (!doneFlag) + doneFlag = journal.handleEvents(_key); + } while (!_vm->shouldQuit() && !doneFlag); + + // Finish up + _infoFlag = _keyboardInput = false; + _keycode = Common::KEYCODE_INVALID; + _windowOpen = false; + _windowBounds.top = CONTROLS_Y1; + _key = -1; + + // Reset the palette + screen.setPalette(screen._cMap); + + screen._backBuffer1.blitFrom(screen._backBuffer2); + scene.updateBackground(); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); // TODO } -- cgit v1.2.3 From d17dea4afd76cba7280e3ffafd1e78a09430e983 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 5 Apr 2015 14:49:02 -0500 Subject: SHERLOCK: Fix journal initalization and initial calls --- engines/sherlock/journal.cpp | 36 ++++++++++++++++-------------------- engines/sherlock/journal.h | 4 ++-- engines/sherlock/objects.cpp | 14 +++++++------- engines/sherlock/talk.cpp | 15 ++++++++++----- 4 files changed, 35 insertions(+), 34 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index b05cc03372..2811c463a2 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -50,9 +50,6 @@ const int SEARCH_POINTS[3][3] = { /*----------------------------------------------------------------*/ Journal::Journal(SherlockEngine *vm): _vm(vm) { - // Allow up to 1000 statements - _journal.resize(1000); - // Initialize fields _count = 0; _maxPage = 0; @@ -70,12 +67,12 @@ Journal::Journal(SherlockEngine *vm): _vm(vm) { * Records statements that are said, in the order which they are said. The player * can then read the journal to review them */ -void Journal::record(int converseNum, int statementNum) { +void Journal::record(int converseNum, int statementNum, bool replyOnly) { int saveIndex = _index; int saveSub = _sub; // Record the entry into the list - _journal.push_back(JournalEntry(converseNum, statementNum)); + _journal.push_back(JournalEntry(converseNum, statementNum, replyOnly)); _index = _journal.size() - 1; // Load the text for the new entry to get the number of lines it will have @@ -108,12 +105,12 @@ void Journal::loadJournalLocations() { _directory.resize(dir->readUint16LE()); // Read in each entry + char buffer[17]; for (uint idx = 0; idx < _directory.size(); ++idx) { - Common::String line; - while ((c = dir->readByte()) != 0) - line += c; + dir->read(buffer, 17); + buffer[16] = '\0'; - _directory.push_back(line); + _directory[idx] = Common::String(buffer); } delete dir; @@ -124,7 +121,7 @@ void Journal::loadJournalLocations() { _locations.clear(); while (loc->pos() < loc->size()) { Common::String line; - while ((c = loc->readByte()) != '\0') + while ((c = loc->readByte()) != 0) line += c; _locations.push_back(line); @@ -137,7 +134,7 @@ void Journal::loadJournalLocations() { * Loads the description for the current display index in the journal, and then * word wraps the result to prepare it for being displayed */ -bool Journal::loadJournalFile(bool alreadyLoaded) { +int Journal::loadJournalFile(bool alreadyLoaded) { Inventory &inv = *_vm->_inventory; People &people = *_vm->_people; Screen &screen = *_vm->_screen; @@ -147,7 +144,7 @@ bool Journal::loadJournalFile(bool alreadyLoaded) { Common::String dirFilename = _directory[journalEntry._converseNum]; bool replyOnly = journalEntry._replyOnly; - Common::String locStr(dirFilename.c_str(), dirFilename.c_str() + 4); + Common::String locStr(dirFilename.c_str() + 4, dirFilename.c_str() + 6); int newLocation = atoi(locStr.c_str()); // If not flagged as alrady loaded, load the conversation into script variables @@ -246,7 +243,7 @@ bool Journal::loadJournalFile(bool alreadyLoaded) { const char *replyP = statement._reply.c_str(); while (*replyP) { - char c = *replyP; + char c = *replyP++; // Is it a control character? if (c < 128) { @@ -264,7 +261,8 @@ bool Journal::loadJournalFile(bool alreadyLoaded) { // a comment (which would have added a line), add a carriage return if (!startOfReply && ((!commentJustPrinted && c == '{') || c == '}')) journalString += '"'; - + startOfReply = false; + // Handle setting or clearing comment state if (c == '{') { commentFlag = true; @@ -290,7 +288,7 @@ bool Journal::loadJournalFile(bool alreadyLoaded) { else journalString += inv._names[talk._talkTo]; - const char *strP = replyP + 1; + const char *strP = replyP; char v; do { v = *strP++; @@ -307,12 +305,11 @@ bool Journal::loadJournalFile(bool alreadyLoaded) { // Copy text from the place until either the reply ends, a comment // {} block is started, or a control character is encountered + journalString += c; do { journalString += *replyP++; } while (*replyP && *replyP < 128 && *replyP != '{' && *replyP != '}'); - // Move pointer back, since the outer for loop will increment it again - --replyP; commentJustPrinted = false; } } else if (c == 128) { @@ -327,7 +324,7 @@ bool Journal::loadJournalFile(bool alreadyLoaded) { } startOfReply = false; - c = *++replyP; + c = *replyP++; if ((c - 1) == 0) journalString += "Holmes"; @@ -338,7 +335,7 @@ bool Journal::loadJournalFile(bool alreadyLoaded) { else journalString += inv._names[c - 1]; - const char *strP = replyP + 1; + const char *strP = replyP; char v; do { v = *strP++; @@ -350,7 +347,6 @@ bool Journal::loadJournalFile(bool alreadyLoaded) { journalString += " said, \""; } else { // Control code, so move past it and any parameters - ++replyP; switch (c) { case 129: // Run canim case 130: // Assign side diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h index a5fe1e8d94..894065759b 100644 --- a/engines/sherlock/journal.h +++ b/engines/sherlock/journal.h @@ -60,7 +60,7 @@ private: void loadJournalLocations(); - bool loadJournalFile(bool alreadyLoaded); + int loadJournalFile(bool alreadyLoaded); void doArrows(); @@ -72,7 +72,7 @@ private: public: Journal(SherlockEngine *vm); - void record(int converseNum, int statementNum); + void record(int converseNum, int statementNum, bool replyOnly = false); void drawInterface(); diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index d5d24e72af..e4730ef207 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -191,15 +191,15 @@ void Sprite::checkSprite() { for (uint idx = 0; idx < scene._bgShapes.size() && !talk._talkToAbort; ++idx) { Object &obj = scene._bgShapes[idx]; - if (obj._aType > PERSON && _type != INVALID && _type != HIDDEN) { - if (_type == NO_SHAPE) { - objBounds = Common::Rect(_position.x, _position.y, - _position.x + _noShapeSize.x, _position.y + _noShapeSize.y); + if (obj._aType > PERSON && obj._type != INVALID && obj._type != HIDDEN) { + if (obj._type == NO_SHAPE) { + objBounds = Common::Rect(obj._position.x, obj._position.y, + obj._position.x + obj._noShapeSize.x, obj._position.y + obj._noShapeSize.y); } else { - int xp = _position.x + _imageFrame->_offset.x; - int yp = _position.y + _imageFrame->_offset.y; + int xp = obj._position.x + obj._imageFrame->_offset.x; + int yp = obj._position.y + obj._imageFrame->_offset.y; objBounds = Common::Rect(xp, yp, - xp + _imageFrame->_frame.w, yp + _imageFrame->_frame.h); + xp + obj._imageFrame->_frame.w, yp + obj._imageFrame->_frame.h); } } diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 6596431b8b..d284ace8b8 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -37,20 +37,24 @@ void Statement::synchronize(Common::SeekableReadStream &s) { int length; length = s.readUint16LE(); - for (int idx = 0; idx < length; ++idx) + for (int idx = 0; idx < length - 1; ++idx) _statement += (char)s.readByte(); + s.readByte(); // Null ending length = s.readUint16LE(); - for (int idx = 0; idx < length; ++idx) + for (int idx = 0; idx < length - 1; ++idx) _reply += (char)s.readByte(); + s.readByte(); // Null ending length = s.readUint16LE(); - for (int idx = 0; idx < length; ++idx) + for (int idx = 0; idx < length - 1; ++idx) _linkFile += (char)s.readByte(); + s.readByte(); // Null ending length = s.readUint16LE(); - for (int idx = 0; idx < length; ++idx) + for (int idx = 0; idx < length - 1; ++idx) _voiceFile += (char)s.readByte(); + s.readByte(); // Null ending _required.resize(s.readByte()); _modified.resize(s.readByte()); @@ -280,7 +284,7 @@ void Talk::talkTo(const Common::String &filename) { // Add the statement into the journal and talk history if (_talkTo != -1 && !_talkHistory[_converseNum][select]) - journal.record(_converseNum | 2048, select); + journal.record(_converseNum, select, true); _talkHistory[_converseNum][select] = true; // Check if the talk file is meant to be a non-seen comment @@ -555,6 +559,7 @@ void Talk::loadTalkFile(const Common::String &filename) { // Open the talk file for reading Common::SeekableReadStream *talkStream = res.load(talkFile); + _converseNum = res.resourceIndex(); talkStream->skip(2); // Skip talk file version num _statements.resize(talkStream->readByte()); -- cgit v1.2.3 From 900471834987c32b23b3162e2d2f40bbcc2b593d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 5 Apr 2015 21:35:22 -0500 Subject: SHERLOCK: Fix display of journal --- engines/sherlock/journal.cpp | 12 ++++++++---- engines/sherlock/screen.cpp | 13 +++++++------ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 2811c463a2..f9c2c54289 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -56,7 +56,7 @@ Journal::Journal(SherlockEngine *vm): _vm(vm) { _index = 0; _sub = 0; _up = _down = false; - _page = 0; + _page = 1; _converseNum = -1; // Load the journal directory and location names @@ -140,7 +140,6 @@ int Journal::loadJournalFile(bool alreadyLoaded) { Screen &screen = *_vm->_screen; Talk &talk = *_vm->_talk; JournalEntry &journalEntry = _journal[_index]; - Statement &statement = talk[journalEntry._statementNum]; Common::String dirFilename = _directory[journalEntry._converseNum]; bool replyOnly = journalEntry._replyOnly; @@ -184,6 +183,7 @@ int Journal::loadJournalFile(bool alreadyLoaded) { } // Start building journal string + Statement &statement = talk[journalEntry._statementNum]; Common::String journalString; if (newLocation != oldLocation) { @@ -260,7 +260,7 @@ int Journal::loadJournalFile(bool alreadyLoaded) { // If a reply isn't just being started, and we didn't just end // a comment (which would have added a line), add a carriage return if (!startOfReply && ((!commentJustPrinted && c == '{') || c == '}')) - journalString += '"'; + journalString += '\n'; startOfReply = false; // Handle setting or clearing comment state @@ -434,7 +434,7 @@ int Journal::loadJournalFile(bool alreadyLoaded) { } // Add in the line - _lines.push_back(Common::String(startP, endP)); + _lines.push_back(Common::String(journalString.c_str(), endP)); // Strip line off from string being processed journalString = *endP ? Common::String(endP + 1) : ""; @@ -461,6 +461,10 @@ void Journal::drawInterface() { bg->read(palette, PALETTE_SIZE); delete bg; + // Translate the palette for display + for (int idx = 0; idx < PALETTE_SIZE; ++idx) + palette[idx] = VGA_COLOR_TRANS(palette[idx]); + // Set the palette and print the title screen.setPalette(palette); screen.gPrint(Common::Point(111, 18), BUTTON_BOTTOM, "Watson's Journal"); diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 0eeddf2a5f..a30108118c 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -440,15 +440,16 @@ void Screen::buttonPrint(const Common::Point &pt, byte color, bool slamIt, if (slamIt) { print(Common::Point(xStart, pt.y + 1), COMMAND_HIGHLIGHTED, "%c", str[0]); print(Common::Point(xStart + charWidth(str[0]), pt.y + 1), - color, "%s", str.c_str() + 1); + COMMAND_FOREGROUND, str.c_str() + 1); } else { - print(Common::Point(xStart, pt.y), COMMAND_HIGHLIGHTED, "%c", str[0]); - print(Common::Point(xStart + charWidth(str[0]), pt.y), - color, "%s", str.c_str() + 1); + gPrint(Common::Point(xStart, pt.y), COMMAND_HIGHLIGHTED, "%c", str[0]); + gPrint(Common::Point(xStart + charWidth(str[0]), pt.y), + COMMAND_FOREGROUND, str.c_str() + 1); } + } else if (slamIt) { + print(Common::Point(xStart, pt.y + 1), color, str.c_str()); } else { - print(Common::Point(xStart, slamIt ? pt.y + 1 : pt.y), COMMAND_HIGHLIGHTED, - "%s", str.c_str()); + gPrint(Common::Point(xStart, pt.y), color, str.c_str()); } } -- cgit v1.2.3 From 3ef78ed7e1fccaf6f31f4e317196cace6af577a2 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 5 Apr 2015 22:15:46 -0500 Subject: SHERLOCK: Fix button text for inventory display --- engines/sherlock/inventory.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index f7706c9d64..e58c4ddac6 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -314,16 +314,16 @@ void Inventory::invCommands(bool slamIt) { screen.buttonPrint(Common::Point(INVENTORY_POINTS[3][2], CONTROLS_Y1), _invMode == 3 ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, false, "Give"); - screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1), + screen.gPrint(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1), _invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND, "^^"); - screen.print(Common::Point(INVENTORY_POINTS[5][2], CONTROLS_Y1), + screen.gPrint(Common::Point(INVENTORY_POINTS[5][2], CONTROLS_Y1), _invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND, "^"); - screen.print(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1), + screen.gPrint(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1), (_holdings - _invIndex < 7) ? COMMAND_NULL : COMMAND_FOREGROUND, "_"); - screen.print(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1), + screen.gPrint(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1), (_holdings - _invIndex < 7) ? COMMAND_NULL : COMMAND_FOREGROUND, "__"); } -- cgit v1.2.3 From 49fd689c07be266cf0ad40d3510ac875ac81174c Mon Sep 17 00:00:00 2001 From: Strangerke Date: Wed, 8 Apr 2015 22:55:33 +0200 Subject: SHERLOCK: Implement showAlleyCutscene --- engines/sherlock/scalpel/scalpel.cpp | 38 ++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 0432dc2278..954ea12aec 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -310,8 +310,42 @@ bool ScalpelEngine::showCityCutscene() { } bool ScalpelEngine::showAlleyCutscene() { - // TODO - return true; + byte palette[PALETTE_SIZE]; + _sound->playMusic("prolog2.mus"); + + _titleOverride = "TITLE.LIB"; + _soundOverride = "TITLE.SND"; + + bool finished = _animation->playPrologue("27PRO1", 1, 3, true, 2); + if (finished) + _animation->playPrologue("27PRO2", 1, 0, false, 2); + + if (finished) { + ImageFile screamImages("SCREAM.LBV", false); + _screen->_backBuffer1.transBlitFrom(screamImages[0], Common::Point(0, 0)); + _screen->_backBuffer2.blitFrom(_screen->_backBuffer1); + finished = _events->delay(6000); + } + + if (finished) + _animation->playPrologue("27PRO3", 1, 0, true, 2); + + if(finished) { + _screen->getPalette(palette); + _screen->fadeToBlack(2); + } + + if(finished) { + ImageFile titleImages("title3.vgs", true); + // "Early the following morning on Baker Street..." + _screen->_backBuffer1.transBlitFrom(titleImages[0], Common::Point(35, 51), false, 0); + _screen->fadeIn(palette, 3); + finished = _events->delay(1000); + } + + _titleOverride = ""; + _soundOverride = ""; + return finished; } bool ScalpelEngine::showStreetCutscene() { -- cgit v1.2.3 From d45d1672137843d028c4ddf63ccf9b62d5d72976 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Thu, 9 Apr 2015 00:12:18 +0200 Subject: SHERLOCK: Fix regression in image loading --- engines/sherlock/resources.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index 0d66646286..262832c3c3 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -298,8 +298,8 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette) { frame._width = stream.readUint16LE() + 1; frame._height = stream.readUint16LE() + 1; frame._paletteBase = stream.readByte(); - frame._rleEncoded = stream.readByte() == 1; - frame._offset.x = stream.readByte(); + frame._offset.x = stream.readUint16LE(); + frame._rleEncoded = ((frame._offset.x & 0xFF) == 1); frame._offset.y = stream.readByte(); frame._rleEncoded = !skipPalette && frame._rleEncoded; -- cgit v1.2.3 From 96e04ab797253bbe853f172ea1d734ebe812d419 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 10 Apr 2015 23:35:26 -0500 Subject: SHERLOCK: Implemented doScript and support methods --- engines/sherlock/animation.cpp | 2 +- engines/sherlock/events.cpp | 8 + engines/sherlock/events.h | 2 + engines/sherlock/inventory.cpp | 112 +++++ engines/sherlock/inventory.h | 9 + engines/sherlock/people.cpp | 2 + engines/sherlock/people.h | 2 + engines/sherlock/scene.cpp | 16 +- engines/sherlock/scripts.cpp | 11 +- engines/sherlock/scripts.h | 6 +- engines/sherlock/sherlock.cpp | 6 +- engines/sherlock/sound.cpp | 7 +- engines/sherlock/sound.h | 4 +- engines/sherlock/talk.cpp | 833 +++++++++++++++++++++++++++++++++++- engines/sherlock/talk.h | 31 +- engines/sherlock/user_interface.cpp | 10 +- 16 files changed, 1002 insertions(+), 59 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index e1687b5238..4674151ec7 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -144,7 +144,7 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f Common::String::format("%s%01d", baseName.c_str(), soundNumber) : Common::String::format("%s%02d", baseName.c_str(), soundNumber); - if (sound._voicesOn) + if (sound._voices) sound.playSound(fname); } diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index d147fe1f4c..67d09e52b2 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -100,6 +100,14 @@ bool Events::isCursorVisible() const { return CursorMan.isVisible(); } +/** + * Move the mouse + */ +void Events::moveMouse(const Common::Point &pt) { + g_system->warpMouse(pt.x, pt.y); +} + + /** * Check for any pending events */ diff --git a/engines/sherlock/events.h b/engines/sherlock/events.h index c3bdaf5a93..71f7623002 100644 --- a/engines/sherlock/events.h +++ b/engines/sherlock/events.h @@ -72,6 +72,8 @@ public: bool isCursorVisible() const; + void moveMouse(const Common::Point &pt); + void pollEvents(); void pollEventsAndWait(); diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index e58c4ddac6..0ea85f32fc 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -366,4 +366,116 @@ void Inventory::doInvJF() { } } +/** + * Adds a shape from the scene to the player's inventory + */ +int Inventory::putNameInInventory(const Common::String &name) { + Scene &scene = *_vm->_scene; + int matches = 0; + + for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) { + Object &o = scene._bgShapes[idx]; + if (scumm_stricmp(name.c_str(), o._name.c_str()) == 0 && o._type != INVALID) { + putItemInInventory(o); + ++matches; + } + } + + return matches; +} + +/** + * Moves a specified item into the player's inventory If the item has a *PICKUP* use action, + * then the item in the use action are added to the inventory. + */ +int Inventory::putItemInInventory(Object &obj) { + Scene &scene = *_vm->_scene; + int matches = 0; + bool pickupFound = false; + + if (obj._pickupFlag) + _vm->setFlags(obj._pickupFlag); + + for (int useNum = 0; useNum < 4; ++useNum) { + if (scumm_stricmp(obj._use[useNum]._target.c_str(), "*PICKUP*") == 0) { + pickupFound = true; + + for (int namesNum = 0; namesNum < 4; ++namesNum) { + for (uint bgNum = 0; bgNum < scene._bgShapes.size(); ++bgNum) { + Object &bgObj = scene._bgShapes[bgNum]; + if (scumm_stricmp(obj._use[useNum]._names[namesNum].c_str(), bgObj._name.c_str()) == 0) { + copyToInventory(bgObj); + if (bgObj._pickupFlag) + _vm->setFlags(bgObj._pickupFlag); + + if (bgObj._type == ACTIVE_BG_SHAPE || bgObj._type == NO_SHAPE || bgObj._type == HIDE_SHAPE) { + if (bgObj._imageFrame == nullptr || bgObj._frameNumber < 0) + // No shape to erase, so flag as hidden + bgObj._type = INVALID; + else + bgObj._type = REMOVE; + } else if (bgObj._type == HIDDEN) { + bgObj._type = INVALID; + } + + ++matches; + } + } + } + } + } + + if (!pickupFound) { + // No pickup item found, so add the passed item + copyToInventory(obj); + matches = 0; + } + + if (matches == 0) { + if (!pickupFound) + matches = 1; + + if (obj._type == ACTIVE_BG_SHAPE || obj._type == NO_SHAPE || obj._type == HIDE_SHAPE) { + if (obj._imageFrame == nullptr || obj._frameNumber < 0) + // No shape to erase, so flag as hidden + obj._type = INVALID; + else + obj._type = REMOVE; + } else if (obj._type == HIDDEN) { + obj._type = INVALID; + } + } + + return matches; +} + +/** + * Copy the passed object into the inventory + */ +void Inventory::copyToInventory(Object &obj) { + // TODO +} + +/** + * Deletes a specified item from the player's inventory + */ +int Inventory::deleteItemFromInventory(const Common::String &name) { + int invNum = -1; + + for (int idx = 0; idx < (int)size() && invNum == -1; ++idx) { + if (scumm_stricmp(name.c_str(), (*this)[idx]._name.c_str()) == 0) + invNum = idx; + } + + if (invNum == -1) + // Item not present + return 0; + + // Item found, so delete it + remove_at(invNum); + --_holdings; + + return 1; +} + } // End of namespace Sherlock diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index 55abc4c960..722692a3b2 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -26,6 +26,7 @@ #include "common/scummsys.h" #include "common/array.h" #include "common/str-array.h" +#include "sherlock/objects.h" #include "sherlock/resources.h" namespace Sherlock { @@ -59,6 +60,10 @@ struct InventoryItem { class Inventory : public Common::Array { private: SherlockEngine *_vm; + + int putItemInInventory(Object &obj); + + void copyToInventory(Object &obj); public: ImageFile *_invShapes[MAX_VISIBLE_INVENTORY]; Common::StringArray _names; @@ -90,6 +95,10 @@ public: void highlight(int index, byte color); void doInvJF(); + + int putNameInInventory(const Common::String &name); + + int deleteItemFromInventory(const Common::String &name); }; } // End of namespace Sherlock diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 3da35f2fec..9319fbb79d 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -61,6 +61,8 @@ People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) { _clearingThePortrait = false; _srcZone = _destZone = 0; _talkPics = nullptr; + _portraitSide = 0; + _speakerFlip = false; } People::~People() { diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index a1fad019c8..1a846dded1 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -77,6 +77,8 @@ public: Object _portrait; bool _clearingThePortrait; bool _allowWalkAbort; + int _portraitSide; + bool _speakerFlip; public: People(SherlockEngine *vm); ~People(); diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 7c66a1dc62..3d5f566164 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -89,7 +89,8 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { _currentScene = -1; _goToScene = -1; _changes = false; - _charPoint = _oldCharPoint = 0; + _charPoint = 0; + _oldCharPoint = 39; _keyboardInput = 0; _walkedInScene = false; _ongoingCans = 0; @@ -118,7 +119,7 @@ void Scene::selectScene() { Events &events = *_vm->_events; People &people = *_vm->_people; Screen &screen = *_vm->_screen; - Scripts &scripts = *_vm->_scripts; + Talk &talk = *_vm->_talk; UserInterface &ui = *_vm->_ui; // Reset fields @@ -150,8 +151,8 @@ void Scene::selectScene() { // If there were any scripst waiting to be run, but were interrupt by a running // canimation (probably the last scene's exit canim), clear the _scriptMoreFlag - if (scripts._scriptMoreFlag == 3) - scripts._scriptMoreFlag = 0; + if (talk._scriptMoreFlag == 3) + talk._scriptMoreFlag = 0; } /** @@ -1053,7 +1054,6 @@ void Scene::doBgAnim() { Inventory &inv = *_vm->_inventory; People &people = *_vm->_people; Screen &screen = *_vm->_screen; - Scripts &scripts = *_vm->_scripts; Sound &sound = *_vm->_sound; Talk &talk = *_vm->_talk; UserInterface &ui = *_vm->_ui; @@ -1359,10 +1359,10 @@ void Scene::doBgAnim() { // Check if the method was called for calling a portrait, and a talk was // interrupting it. This talk file would not have been executed at the time, // since we needed to finish the 'doBgAnim' to finish clearing the portrait - if (people._clearingThePortrait && scripts._scriptMoreFlag == 3) { + if (people._clearingThePortrait && talk._scriptMoreFlag == 3) { // Reset the flags and call to talk - people._clearingThePortrait = scripts._scriptMoreFlag = 0; - talk.talkTo(scripts._scriptName); + people._clearingThePortrait = talk._scriptMoreFlag = 0; + talk.talkTo(talk._scriptName); } } diff --git a/engines/sherlock/scripts.cpp b/engines/sherlock/scripts.cpp index d337030bae..02dcfa6f0b 100644 --- a/engines/sherlock/scripts.cpp +++ b/engines/sherlock/scripts.cpp @@ -26,21 +26,16 @@ namespace Sherlock { Scripts::Scripts(SherlockEngine *vm): _vm(vm) { - _scriptMoreFlag = 0; - _scriptSaveIndex = 0; - _scriptSelect = 0; -} -void Scripts::doScript(const Common::String &str) { - // TODO } void Scripts::popStack() { + /* ScriptEntry script = _scriptStack.pop(); _scriptName = script._name; - _scriptSaveIndex = script._index; +// _scriptSaveIndex = script._index; _scriptSelect = script._select; - _scriptMoreFlag = true; + */ } diff --git a/engines/sherlock/scripts.h b/engines/sherlock/scripts.h index 6765687bcf..beea726c8d 100644 --- a/engines/sherlock/scripts.h +++ b/engines/sherlock/scripts.h @@ -40,11 +40,7 @@ class Scripts { private: SherlockEngine *_vm; public: - Common::Stack _scriptStack; - int _scriptMoreFlag; - Common::String _scriptName; - int _scriptSaveIndex; - int _scriptSelect; + public: Scripts(SherlockEngine *vm); diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 20a805594e..2a1b456b76 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -122,10 +122,10 @@ void SherlockEngine::sceneLoop() { while (!shouldQuit() && _scene->_goToScene == -1) { // See if a script needs to be completed from either a goto room code, // or a script that was interrupted by another script - if (_scripts->_scriptMoreFlag == 1 || _scripts->_scriptMoreFlag == 3) - _talk->talkTo(_scripts->_scriptName); + if (_talk->_scriptMoreFlag == 1 || _talk->_scriptMoreFlag == 3) + _talk->talkTo(_talk->_scriptName); else - _scripts->_scriptMoreFlag = 0; + _talk->_scriptMoreFlag = 0; // Handle any input from the keyboard or mouse handleInput(); diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index 5e7df5607f..771d5db9d5 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -27,7 +27,8 @@ namespace Sherlock { Sound::Sound(SherlockEngine *vm): _vm(vm) { _soundOn = true; _musicOn = true; - _voicesOn = true; + _speechOn = true; + _voices = 0; _playingEpilogue = false; _music = false; _digitized = false; @@ -89,5 +90,9 @@ void Sound::freeSong() { // TODO } +void Sound::stopSndFuncPtr(int v1, int v2) { + // TODO +} + } // End of namespace Sherlock diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index 74e8db3611..22d5a5c221 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -40,7 +40,8 @@ private: public: bool _soundOn; bool _musicOn; - bool _voicesOn; + bool _speechOn; + int _voices; bool _playingEpilogue; bool _music; bool _digitized; @@ -64,6 +65,7 @@ public: void playMusic(const Common::String &name); void stopMusic(); + void stopSndFuncPtr(int v1, int v2); }; } // End of namespace Sherlock diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index d284ace8b8..193c0f9a19 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -26,7 +26,42 @@ namespace Sherlock { -#define SFX_COMMAND 140 +enum { + SWITCH_SPEAKER = 128, + RUN_CANIMATION = 129, + ASSIGN_PORTRAIT_LOCATION = 130, + PAUSE = 131, + REMOVE_PORTRAIT = 132, + CLEAR_WINDOW = 133, + ADJUST_OBJ_SEQUENCE = 134, + WALK_TO_COORDS = 135, + PAUSE_WITHOUT_CONTROL = 136, + BANISH_WINDOW = 137, + SUMMON_WINDOW = 138, + SET_FLAG = 139, + SFX_COMMAND = 140, + TOGGLE_OBJECT = 141, + STEALTH_MODE_ACTIVE = 142, + IF_STATEMENT = 143, + ELSE_STATEMENT = 144, + END_IF_STATEMENT = 145, + STEALTH_MODE_DEACTIVATE = 146, + TURN_HOLMES_OFF = 147, + TURN_HOLMES_ON = 148, + GOTO_SCENE = 149, + PLAY_PROLOGUE = 150, + ADD_ITEM_TO_INVENTORY = 151, + SET_OBJECT = 152, + CALL_TALK_FILE = 153, + MOVE_MOUSE = 154, + DISPLAY_INFO_LINE = 155, + CLEAR_INFO_LINE = 156, + WALK_TO_CANIMATION = 157, + REMOVE_ITEM_FROM_INVENTORY = 158, + ENABLE_END_KEY = 159, + DISABLE_END_KEY = 160, + COMMAND_161 = 161 +}; /*----------------------------------------------------------------*/ @@ -99,6 +134,9 @@ Talk::Talk(SherlockEngine *vm): _vm(vm) { _talkStealth = 0; _talkToFlag = -1; _moreTalkDown = _moreTalkUp = false; + _scriptMoreFlag = 1; + _scriptSaveIndex = -1; + _scriptCurrentIndex = -1; } void Talk::setSequences(const byte *talkSequences, const byte *stillSequences, int maxPeople) { @@ -136,13 +174,13 @@ void Talk::talkTo(const Common::String &filename) { // save the filename for later executing when the canimation is done if (scene._ongoingCans || people._clearingThePortrait) { // Make sure we're not in the middle of a script - if (!scripts._scriptMoreFlag) { - scripts._scriptName = filename; - scripts._scriptSaveIndex = 0; + if (!_scriptMoreFlag) { + _scriptName = filename; + _scriptSaveIndex = 0; // Flag the selection, since we don't yet know which statement yet - scripts._scriptSelect = 100; - scripts._scriptMoreFlag = 3; + _scriptSelect = 100; + _scriptMoreFlag = 3; } return; @@ -172,7 +210,7 @@ void Talk::talkTo(const Common::String &filename) { // If any sequences have changed in the prior talk file, restore them if (_savedSequences.size() > 0) { for (uint idx = 0; idx < _savedSequences.size(); ++idx) { - SavedSequence &ss = _savedSequences[idx]; + SequenceEntry &ss = _savedSequences[idx]; for (uint idx2 = 0; idx2 < _savedSequences.size(); ++idx2) scene._bgShapes[ss._objNum]._sequences[idx2] = ss._sequences[idx2]; @@ -181,7 +219,7 @@ void Talk::talkTo(const Common::String &filename) { } } - while (!_sequenceStack.empty()) + while (!_scriptStack.empty()) pullSequence(); // Restore any pressed button @@ -276,7 +314,7 @@ void Talk::talkTo(const Common::String &filename) { select = _talkIndex = idx; } - if (scripts._scriptMoreFlag && _scriptSelect != 0) + if (_scriptMoreFlag && _scriptSelect != 0) select = _scriptSelect; if (select == -1) @@ -288,7 +326,7 @@ void Talk::talkTo(const Common::String &filename) { _talkHistory[_converseNum][select] = true; // Check if the talk file is meant to be a non-seen comment - if (filename[7] != '*') { + if (filename.size() < 8 || filename[7] != '*') { // Should we start in stealth mode? if (_statements[select]._statement.hasPrefix("^")) { _talkStealth = 2; @@ -305,13 +343,13 @@ void Talk::talkTo(const Common::String &filename) { // Handle replies until there's no further linked file, // or the link file isn't a reply first cnversation - for (;;) { + while (!_vm->shouldQuit()) { clearSequences(); _scriptSelect = select; _speaker = _talkTo; Statement &statement = _statements[select]; - scripts.doScript(_statements[select]._reply); + doScript(_statements[select]._reply); if (_talkToAbort) return; @@ -327,7 +365,7 @@ void Talk::talkTo(const Common::String &filename) { } // Check for a linked file - if (!statement._linkFile.empty() && !scripts._scriptMoreFlag) { + if (!statement._linkFile.empty() && !_scriptMoreFlag) { freeTalkVars(); loadTalkFile(statement._linkFile); @@ -422,7 +460,7 @@ void Talk::talkTo(const Common::String &filename) { // If a script was added to the script stack, restore state so that the // previous script can continue - if (!scripts._scriptStack.empty()) { + if (!_scriptStack.empty()) { scripts.popStack(); } @@ -547,7 +585,7 @@ void Talk::loadTalkFile(const Common::String &filename) { // Check for an existing person being talked to _talkTo = -1; for (int idx = 0; idx < MAX_PEOPLE; ++idx) { - if (scumm_strnicmp(filename.c_str(), people[(PeopleId)idx]._portrait.c_str(), 4)) { + if (!scumm_strnicmp(filename.c_str(), people[(PeopleId)idx]._portrait.c_str(), 4)) { _talkTo = idx; break; } @@ -568,7 +606,7 @@ void Talk::loadTalkFile(const Common::String &filename) { delete talkStream; - if (!sound._voicesOn) + if (!sound._voices) stripVoiceCommands(); setTalkMap(); } @@ -833,7 +871,7 @@ int Talk::talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt * Clears the stack of pending object sequences associated with speakers in the scene */ void Talk::clearSequences() { - _sequenceStack.clear(); + _scriptStack.clear(); } /** @@ -843,7 +881,7 @@ void Talk::clearSequences() { void Talk::pullSequence() { Scene &scene = *_vm->_scene; - SequenceEntry seq = _sequenceStack.pop(); + SequenceEntry seq = _scriptStack.pop(); if (seq._objNum != -1) { Object &obj = scene._bgShapes[seq._objNum]; @@ -871,7 +909,7 @@ void Talk::pushSequence(int speaker) { if (speaker == -1) return; - SequenceEntry seqEntry; + ScriptStackEntry seqEntry; if (!speaker) { seqEntry._objNum = -1; } else { @@ -885,9 +923,13 @@ void Talk::pushSequence(int speaker) { seqEntry._seqTo = obj._seqTo; } - _sequenceStack.push(seqEntry); - if (_sequenceStack.size() >= 5) - error("sequence stack overflow"); + _scriptStack.push(seqEntry); + if (_scriptStack.size() >= 5) + error("script stack overflow"); +} + +void Talk::setSequence(int speaker) { + // TODO } /** @@ -923,4 +965,751 @@ void Talk::setStillSeq(int speaker) { } } +/** + * Parses a reply for control codes and display text. The found text is printed within + * the text window, handles delays, animations, and animating portraits. + */ +void Talk::doScript(const Common::String &script) { + Animation &anim = *_vm->_animation; + Events &events = *_vm->_events; + Inventory &inv = *_vm->_inventory; + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + Screen &screen = *_vm->_screen; + Sound &sound = *_vm->_sound; + UserInterface &ui = *_vm->_ui; + int wait = 0; + bool pauseFlag = false; + bool endStr = false; + int yp = CONTROLS_Y + 12; + int charCount = 0; + int line = 0; + bool noTextYet = true; + bool openTalkWindow = false; + int obj; + int seqCount; + + _saveSeqNum = 0; + + const char *str = script.c_str(); + if (_scriptMoreFlag) { + _scriptMoreFlag = 0; + str = script.c_str() + _scriptSaveIndex; + } + + // Check if the script begins with a Stealh Mode Active command + if (str[0] == STEALTH_MODE_ACTIVE || _talkStealth) { + _talkStealth = 2; + _speaker |= 128; + } else { + pushSequence(_speaker); + ui.clearWindow(); + + // Need to switch speakers? + if (str[0] == SWITCH_SPEAKER) { + _speaker = str[1] - 1; + str += 2; + pullSequence(); + pushSequence(_speaker); + setSequence(_speaker); + } + else { + setSequence(_speaker); + } + + // Assign portrait location? + if (str[0] == ASSIGN_PORTRAIT_LOCATION) { + switch (str[1] & 15) { + case 1: + people._portraitSide = 20; + break; + case 2: + people._portraitSide = 220; + break; + case 3: + people._portraitSide = 120; + break; + default: + break; + + } + + if (str[1] > 15) + people._speakerFlip = true; + str += 2; + } + + // Remove portrait? + if (str[0] == REMOVE_PORTRAIT) { + _speaker = 255; + } + else { + // Nope, so set the first speaker + setTalking(_speaker); + } + } + + do { + Common::String tempString; + wait = 0; + + if (!str[0]) { + endStr = true; + } else if (str[0] == '{') { + // Start of comment, so skip over it + while (*str++ != '}') + ; + } else if (str[0] >= 128) { + // Handle control code + switch (str[0]) { + case SWITCH_SPEAKER: + // Save the current point in the script, since it might be intterupted by + // doing bg anims in the next call, so we need to know where to return to + _scriptCurrentIndex = str - script.c_str(); + + if (!(_speaker & 128)) + clearTalking(); + if (_talkToAbort) + return; + + ui.clearWindow(); + yp = CONTROLS_Y + 12; + charCount = line = 0; + + _speaker = *++str - 1; + setTalking(_speaker); + pullSequence(); + pushSequence(_speaker); + setSequence(_speaker); + break; + + case RUN_CANIMATION: + // Save the current point in the script, since it might be intterupted by + // doing bg anims in the next call, so we need to know where to return to + _scriptCurrentIndex = str - script.c_str(); + scene.startCAnim((str[0] - 1) & 127, 1 + (str[0] & 128)); + if (_talkToAbort) + return; + + // Check if next character is changing side or changing portrait + if (charCount && (str[1] == SWITCH_SPEAKER || str[1] == ASSIGN_PORTRAIT_LOCATION)) + wait = 1; + break; + + case ASSIGN_PORTRAIT_LOCATION: + ++str; + switch (str[0] & 15) { + case 1: + people._portraitSide = 20; + break; + case 2: + people._portraitSide = 220; + break; + case 3: + people._portraitSide = 120; + break; + default: + break; + } + + if (str[0] > 15) + people._speakerFlip = true; + break; + + case PAUSE: + // Pause + charCount = *++str; + wait = pauseFlag = true; + break; + + case REMOVE_PORTRAIT: + // Save the current point in the script, since it might be intterupted by + // doing bg anims in the next call, so we need to know where to return to + _scriptCurrentIndex = str - script.c_str(); + + if (_speaker < 128) + clearTalking(); + pullSequence(); + if (_talkToAbort) + return; + + _speaker |= 128; + break; + + case CLEAR_WINDOW: + ui.clearWindow(); + yp = CONTROLS_Y + 12; + charCount = line = 0; + break; + + case ADJUST_OBJ_SEQUENCE: + // Get the name of the object to adjust + ++str; + for (int idx = 0; idx < (str[0] & 127); ++idx) + tempString += str[idx + 2]; + + // Scan for object + obj = -1; + for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) { + if (scumm_stricmp(tempString.c_str(), scene._bgShapes[idx]._name.c_str()) == 0) + obj = idx; + } + if (obj == -1) + error("Could not find object %s to change", tempString.c_str()); + + // Should the script be overwritten? + if (str[0] > 128) { + // Save the current sequence + _savedSequences.push(SequenceEntry()); + SequenceEntry &seqEntry = _savedSequences.top(); + seqEntry._objNum = obj; + seqEntry._seqTo = scene._bgShapes[obj]._seqTo; + for (uint idx = 0; idx < scene._bgShapes[obj]._seqSize; ++idx) + seqEntry._sequences.push_back(scene._bgShapes[obj]._sequences[idx]); + } + + // Get number of bytes to change + seqCount = str[1]; + str += (str[0] & 127) + 2; + + // Copy in the new sequence + for (int idx = 0; idx < seqCount; ++idx, ++str) + scene._bgShapes[obj]._sequences[idx] = str[0] - 1; + + // Reset object back to beginning of new sequence + scene._bgShapes[obj]._frameNumber = 0; + continue; + + case WALK_TO_COORDS: + // Save the current point in the script, since it might be intterupted by + // doing bg anims in the next call, so we need to know where to return to + _scriptCurrentIndex = str - script.c_str(); + + people.walkToCoords(Common::Point(((str[0] - 1) * 256 + str[1] - 1) * 100, str[2] * 100), str[3] - 1); + if (_talkToAbort) + return; + + str += 3; + break; + + case PAUSE_WITHOUT_CONTROL: + // Save the current point in the script, since it might be intterupted by + // doing bg anims in the next call, so we need to know where to return to + _scriptCurrentIndex = str - script.c_str(); + + for (int idx = 0; idx < (str[0] - 1); ++idx) { + scene.doBgAnim(); + if (_talkToAbort) + return; + + // Check for button press + events.pollEvents(); + events.setButtonState(); + } + break; + + case BANISH_WINDOW: + // Save the current point in the script, since it might be intterupted by + // doing bg anims in the next call, so we need to know where to return to + _scriptCurrentIndex = str - script.c_str(); + + if (!(_speaker & 128)) + clearTalking(); + pullSequence(); + + if (_talkToAbort) + return; + + _speaker |= 128; + ui.banishWindow(); + ui._menuMode = TALK_MODE; + noTextYet = true; + break; + + case SUMMON_WINDOW: + drawInterface(); + events._pressed = events._released = false; + events.clearKeyboard(); + noTextYet = false; + + if (_speaker != -1) { + screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_NULL, false, "Exit"); + screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_NULL, false, "Up"); + screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, false, "Down"); + } + break; + + case SET_FLAG: { + ++str; + int flag1 = (str[0] - 1) * 256 + str[1] - 1 - (str[1] == 1 ? 1 : 0); + int flag = (flag1 & 0x7fff) * (flag1 >= 0x8000 ? -1 : 1); + _vm->setFlags(flag); + ++str; + break; + } + + case SFX_COMMAND: + ++str; + if (sound._voices) { + for (int idx = 0; idx < 8 && str[idx] != '~'; ++idx) + tempString += str[idx]; + sound.playSound(tempString); + + // Set voices to wait for more + sound._voices = 2; + sound._speechOn = (*sound._soundIsOn); + } + + wait = 1; + str += 7; + break; + + case TOGGLE_OBJECT: + for (int idx = 0; idx < str[0]; ++idx) + tempString += str[idx + 1]; + + scene.toggleObject(tempString); + str += str[0]; + break; + + case STEALTH_MODE_ACTIVE: + _talkStealth = 2; + break; + + case IF_STATEMENT: { + ++str; + int flag = (str[0] - 1) * 256 + str[1] - 1 - (str[1] == 1 ? 1 : 0); + ++str; + wait = 0; + + bool result = flag < 0x8000; + if (_vm->readFlags(flag & 0x7fff) != result) { + do { + ++str; + } while (str[0] && str[0] != ELSE_STATEMENT && str[0] != END_IF_STATEMENT); + + if (!str[0]) + endStr = true; + } + break; + } + + case ELSE_STATEMENT: + // If this is encountered here, it means that a preceeding IF statement was found, + // and evaluated to true. Now all the statements for the true block are finished, + // so skip over the block of code that would have executed if the result was false + wait = 0; + do { + ++str; + } while (str[0] && str[0] != END_IF_STATEMENT); + break; + + case STEALTH_MODE_DEACTIVATE: + _talkStealth = 0; + events.clearKeyboard(); + break; + + case TURN_HOLMES_OFF: + people._holmesOn = false; + break; + + case TURN_HOLMES_ON: + people._holmesOn = true; + break; + + case GOTO_SCENE: + scene._goToScene = str[1] - 1; + + if (scene._goToScene != 100) { + // Not going to the map overview + scene._oldCharPoint = scene._goToScene; + scene._overPos.x = _vm->_map[scene._goToScene].x * 100 - 600; + scene._overPos.y = _vm->_map[scene._goToScene].y * 100 + 900; + + // Run a canimation? + if (str[2] > 100) { + scene._hsavedFs = str[2]; + scene._hsavedPos = Common::Point(160, 100); + } + } + str += 6; + + _scriptMoreFlag = (scene._goToScene == 100) ? 2 : 1; + _scriptSaveIndex = str - script.c_str(); + endStr = true; + wait = 0; + break; + + case PLAY_PROLOGUE: + ++str; + for (int idx = 0; idx < 8 && str[idx] != '~'; ++idx) + tempString += str[idx]; + + anim.playPrologue(tempString, 1, 3, true, 4); + break; + + case ADD_ITEM_TO_INVENTORY: + ++str; + for (int idx = 0; idx < str[0]; ++idx) + tempString += str[idx]; + str += str[0]; + + inv.putNameInInventory(tempString); + break; + + case SET_OBJECT: { + ++str; + for (int idx = 0; idx < (str[0] & 127); ++idx) + tempString += str[idx + 1]; + str += str[0]; + + // Set comparison state according to if we want to hide or unhide + bool state = (str[0] >= 128); + + for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) { + Object &obj = scene._bgShapes[idx]; + if (scumm_stricmp(tempString.c_str(), obj._name.c_str()) == 0) { + // Only toggle the object if it's not in the desired state already + if ((obj._type == HIDDEN && state) || (obj._type != HIDDEN && !state)) + obj.toggleHidden(); + } + } + break; + } + + case CALL_TALK_FILE: + ++str; + for (int idx = 0; idx < 8 && str[idx] != '~'; ++idx) + tempString += str[idx]; + str += 8; + + _scriptCurrentIndex = str - script.c_str(); + + // Save the current script position and new talk file + if (_scriptStack.size() < 10) { + ScriptStackEntry rec; + rec._name = _scriptName; + rec._currentIndex = _scriptCurrentIndex; + rec._select = _scriptSelect; + } else { + error("Script stack overflow"); + } + + _scriptMoreFlag = true; + endStr = true; + wait = 0; + break; + + case MOVE_MOUSE: + // Save the current point in the script, since it might be intterupted by + // doing bg anims in the next call, so we need to know where to return to + _scriptCurrentIndex = str - script.c_str(); + events.moveMouse(Common::Point((str[0] - 1) * 256 + str[1] - 1, str[2])); + if (_talkToAbort) + return; + str += 3; + break; + + case DISPLAY_INFO_LINE: + ++str; + for (int idx = 0; idx < str[0]; ++idx) + tempString += str[idx + 1]; + str += str[0]; + + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, tempString.c_str()); + break; + + case CLEAR_INFO_LINE: + ui._infoFlag = true; + ui.clearInfo(); + break; + + case WALK_TO_CANIMATION: { + ++str; + int animIndex = str[0] - 1; + + // Save the current point in the script, since it might be intterupted by + // doing bg anims in the next call, so we need to know where to return to + _scriptCurrentIndex = (str + 1) - script.c_str(); + if (_talkToAbort) + return; + break; + } + + case REMOVE_ITEM_FROM_INVENTORY: + ++str; + for (int idx = 0; idx < str[0]; ++idx) + tempString += str[idx + 1]; + str += str[0]; + + inv.deleteItemFromInventory(tempString); + break; + + case ENABLE_END_KEY: + ui._endKeyActive = true; + break; + + case DISABLE_END_KEY: + ui._endKeyActive = false; + break; + + default: + break; + } + + ++str; + } else { + // If the window isn't yet open, draw the window before printing starts + if (!ui._windowOpen && noTextYet) { + noTextYet = false; + drawInterface(); + + if (_talkTo != -1) { + screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_NULL, false, "Exit"); + screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_NULL, false, "Up"); + screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, false, "Down"); + } + } + + // If it's the first line, display the speaker + if (!line && _speaker >= 0 && _speaker < MAX_PEOPLE) { + // If the window is open, display the name directly on-screen. + // Otherwise, simply draw it on the back buffer + if (ui._windowOpen) { + screen.print(Common::Point(16, yp), TALK_FOREGROUND, inv._names[_speaker & 127].c_str()); + } else { + screen.gPrint(Common::Point(16, yp - 1), TALK_FOREGROUND, inv._names[_speaker & 127].c_str()); + openTalkWindow = true; + } + + yp += 9; + } + + // Find amound of text that will fit on the line + int width = 0, idx = 0; + do { + width += screen.charWidth(str[idx]); + } while (width < 298 && str[idx] && str[idx] != '{' && str[idx] < 128); + + if (str[idx] || width >= 298) { + if (str[idx] < 128 && str[idx] != '{') { + --idx; + --charCount; + } + } else { + endStr = true; + } + + // If word wrap is needed, find the start of the current word + if (width >= 298) { + while (str[idx] != ' ') { + --idx; + --charCount; + } + } + + // Print the line + Common::String lineStr(str, str + idx); + + // If the speaker indicates a description file, print it in yellow + if (_speaker != -1) { + if (ui._windowOpen) { + screen.print(Common::Point(16, yp), INV_FOREGROUND, lineStr.c_str()); + } else { + screen.gPrint(Common::Point(16, yp - 1), INV_FOREGROUND, lineStr.c_str()); + } + } else { + if (ui._windowOpen) { + screen.print(Common::Point(16, yp), COMMAND_FOREGROUND, lineStr.c_str()); + } + else { + screen.gPrint(Common::Point(16, yp - 1), COMMAND_FOREGROUND, lineStr.c_str()); + } + } + + // Move to end of displayed line + str += idx; + + // If line wrap occurred, then move to after the separating space between the words + if (str[0] < 128 && str[0] != '{') + ++str; + + yp += 9; + ++line; + + // Certain different conditions require a wait + if ((line == 4 && str[0] != SFX_COMMAND && str[0] != PAUSE && _speaker != -1) || + (line == 5 && str[0] != PAUSE && _speaker != -1) || + endStr) { + wait = 1; + } + + switch (str[0]) { + case SWITCH_SPEAKER: + case ASSIGN_PORTRAIT_LOCATION: + case BANISH_WINDOW: + case IF_STATEMENT: + case ELSE_STATEMENT: + case END_IF_STATEMENT: + case GOTO_SCENE: + case CALL_TALK_FILE: + wait = 1; + break; + default: + break; + } + } + + // Open window if it wasn't already open, and text has already been printed + if ((openTalkWindow && wait) || (openTalkWindow && str[0] >= 128 && str[0] != COMMAND_161)) { + if (!ui._windowStyle) { + screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + } else { + ui.summonWindow(); + } + + ui._windowOpen = true; + openTalkWindow = false; + } + + if (wait) { + // Save the current point in the script, since it might be intterupted by + // doing bg anims in the next call, so we need to know where to return to + _scriptCurrentIndex = str - script.c_str(); + + // Handling pausing + if (!pauseFlag && charCount < 160) + charCount = 160; + + wait = waitForMore(charCount); + if (wait == -1) + endStr = true; + + // If a key was pressed to finish the window, see if further voice files should be skipped + if (wait >= 0 && wait < 254) { + if (str[0] == SFX_COMMAND) + str += 9; + } + + // Clear the window unless the wait was due to a PAUSE command + if (!pauseFlag && wait != -1 && str[0] != SFX_COMMAND) { + if (!_talkStealth) + ui.clearWindow(); + yp = CONTROLS_Y + 12; + charCount = line = 0; + } + + pauseFlag = false; + } + } while (!_vm->shouldQuit() && !endStr); + + if (wait != -1) { + for (int ssIndex = 0; ssIndex < (int)_savedSequences.size(); ++ssIndex) { + SequenceEntry &seq = _savedSequences[ssIndex]; + Object &obj = scene._bgShapes[seq._objNum]; + + for (uint idx = 0; idx < seq._sequences.size(); ++idx) + obj._sequences[idx] = seq._sequences[idx]; + obj._frameNumber = seq._frameNumber; + obj._seqTo = seq._seqTo; + } + + pullSequence(); + if (_speaker < 128) + clearTalking(); + } +} + +void Talk::clearTalking() { + // TODO +} + +void Talk::setTalking(int speaker) { + // TODO +} + +/** + * When the talk window has been displayed, waits a period of time proportional to + * the amount of text that's been displayed + */ +int Talk::waitForMore(int delay) { + Events &events = *_vm->_events; + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + Sound &sound = *_vm->_sound; + UserInterface &ui = *_vm->_ui; + CursorId oldCursor = events.getCursor(); + int key2 = 254; + + // Unless we're in stealth mode, show the appropriate cursor + if (!_talkStealth) { + events.setCursor(ui._lookScriptFlag ? MAGNIFY : ARROW); + } + + do { + if (sound._speechOn && !*sound._soundIsOn) + people._portrait._frameNumber = -1; + + scene.doBgAnim(); + + // If talkTo call was done via doBgAnim, abort out of talk quietly + if (_talkToAbort) { + key2 = -1; + events._released = true; + } else { + // See if there's been a button press + events.setButtonState(); + + if (events.kbHit()) { + Common::KeyState keyState = events.getKey(); + if (keyState.keycode >= 32 && keyState.keycode < 128) + key2 = keyState.keycode; + } + + if (_talkStealth) { + key2 = 254; + events._released = false; + } + } + + // Count down the delay + if ((delay > 0 && !ui._invLookFlag && !ui._lookScriptFlag) || _talkStealth) + --delay; + + // If there are voices playing, reset delay so that they keep playing + if (sound._voices == 2 && *sound._soundIsOn) + delay = 0; + } while (!_vm->shouldQuit() && key2 == 254 && (delay || (sound._voices == 2 && *sound._soundIsOn)) + && !events._released && !events._rightReleased); + + // If voices was set 2 to indicate a voice file was place, then reset it back to 1 + if (sound._voices == 2) + sound._voices = 1; + + if (delay > 0 && sound._diskSoundPlaying) + sound.stopSndFuncPtr(0, 0); + + // Adjust _talkStealth mode: + // mode 1 - It was by a pause without stealth being on before the pause, so reset back to 0 + // mode 3 - It was set by a pause with stealth being on before the pause, to set it to active + // mode 0/2 (Inactive/active) No change + switch (_talkStealth) { + case 1: + _talkStealth = 0; + break; + case 2: + _talkStealth = 2; + break; + default: + break; + } + + sound._speechOn = false; + events.setCursor(_talkToAbort ? ARROW : oldCursor); + events._pressed = events._released = false; + + return key2; +} + + } // End of namespace Sherlock diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index 48cdd2b5b2..1b679a47bd 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -33,16 +33,19 @@ namespace Sherlock { #define MAX_TALK_SEQUENCES 11 -struct SavedSequence { +struct SequenceEntry { int _objNum; Common::Array _sequences; -}; - -struct SequenceEntry : public SavedSequence { int _frameNumber; int _seqTo; }; +struct ScriptStackEntry : public SequenceEntry { + Common::String _name; + int _currentIndex; + int _select; +}; + struct Statement { Common::String _statement; Common::String _reply; @@ -84,8 +87,8 @@ private: private: SherlockEngine *_vm; int _saveSeqNum; - Common::Array _savedSequences; - Common::Stack _sequenceStack; + Common::Stack _savedSequences; + Common::Stack _scriptStack; Common::Array _statements; TalkHistoryEntry _talkHistory[500]; int _speaker; @@ -95,17 +98,28 @@ private: int _talkStealth; int _talkToFlag; bool _moreTalkUp, _moreTalkDown; - + int _scriptSaveIndex; + int _scriptCurrentIndex; +private: void stripVoiceCommands(); void setTalkMap(); bool displayTalk(bool slamIt); int talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt); + + void doScript(const Common::String &script); + + void clearTalking(); + void setTalking(int speaker); + + int waitForMore(int delay); public: bool _talkToAbort; int _talkCounter; int _talkTo; + int _scriptMoreFlag; + Common::String _scriptName; public: Talk(SherlockEngine *vm); void setSequences(const byte *talkSequences, const byte *stillSequences, @@ -127,7 +141,8 @@ public: void clearSequences(); void pullSequence(); void pushSequence(int speaker); - bool isSequencesEmpty() const { return _sequenceStack.empty(); } + void setSequence(int speaker); + bool isSequencesEmpty() const { return _scriptStack.empty(); } }; } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 289bff814f..88265f6a19 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -122,7 +122,6 @@ void UserInterface::handleInput() { People &people = *_vm->_people; Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; - Scripts &scripts = *_vm->_scripts; Talk &talk = *_vm->_talk; if (_menuCounter) @@ -148,7 +147,7 @@ void UserInterface::handleInput() { } // Do button highlighting check - if (!scripts._scriptMoreFlag) { // Don't if scripts are running + if (!talk._scriptMoreFlag) { // Don't if scripts are running if (((events._rightPressed || events._rightReleased) && _helpStyle) || (!_helpStyle && !_menuCounter)) { // Handle any default commands if we're in STD_MODE @@ -532,6 +531,13 @@ void UserInterface::examine() { _vm->setFlags(inv[_selector]._lookFlag); } + if (_invLookFlag) { + // Dont close the inventory window when starting an examine display, since it's + // window will slide up to replace the inventory display + _windowOpen = false; + _menuMode = LOOK_MODE; + } + if (!talk._talkToAbort) { if (!scene._cAnimFramePause) printObjectDesc(_cAnimStr, true); -- cgit v1.2.3 From 0d4d8e878cfba4ea9c32dc46e4923886df95395c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 11 Apr 2015 16:52:19 -0500 Subject: SHERLOCK: Implemented stubbed talk and inventory methods --- engines/sherlock/inventory.cpp | 10 +- engines/sherlock/inventory.h | 1 + engines/sherlock/people.cpp | 223 ++++++++++++++++++++++++++++++++++++++++- engines/sherlock/people.h | 10 +- engines/sherlock/talk.cpp | 59 +++++++---- engines/sherlock/talk.h | 3 - 6 files changed, 276 insertions(+), 30 deletions(-) diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index 0ea85f32fc..9eedac7c6a 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -453,7 +453,15 @@ int Inventory::putItemInInventory(Object &obj) { * Copy the passed object into the inventory */ void Inventory::copyToInventory(Object &obj) { - // TODO + InventoryItem invItem; + invItem._name = obj._name; + invItem._description = obj._description; + invItem._examine = obj._examine; + invItem._lookFlag = obj._lookFlag; + invItem._requiredFlag = obj._requiredFlag; + + insert_at(_holdings, invItem); + ++_holdings; } /** diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index 722692a3b2..436d2bc18d 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -53,6 +53,7 @@ struct InventoryItem { Common::String _examine; int _lookFlag; + InventoryItem() : _requiredFlag(0), _lookFlag(0) {} InventoryItem(int requiredFlag, const Common::String &name, const Common::String &description, const Common::String &examine); }; diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 9319fbb79d..5c7f9ef506 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -50,6 +50,145 @@ static const uint8 CHARACTER_SEQUENCES[MAX_HOLMES_SEQUENCE][MAX_FRAME] = { { 52, 1, 2, 3, 4, 0 } // Goto Stand Down Left }; +const char PORTRAITS[MAX_PEOPLE][5] = { + { "HOLM" }, // Sherlock Holmes + { "WATS" }, // Dr. Watson + { "LEST" }, // Inspector Lestrade + { "CON1" }, // Constable O'Brien + { "CON2" }, // Constable Lewis + { "SHEI" }, // Sheila Parker + { "HENR" }, // Henry Carruthers + { "LESL" }, // Lesley (flower girl) + { "USH1" }, // Usher #1 + { "USH2" }, // Usher #2 + { "FRED" }, // Fredrick Epstein + { "WORT" }, // Mrs. Worthington + { "COAC" }, // Coach + { "PLAY" }, // Player + { "WBOY" }, // Tim (Waterboy) + { "JAME" }, // James Sanders + { "BELL" }, // Belle (perfumerie) + { "GIRL" }, // Cleaning Girl (perfumerie) + { "EPST" }, // Epstien in the Opera Balcony + { "WIGG" }, // Wiggins + { "PAUL" }, // Paul (Brumwell / Carroway) + { "BART" }, // Bartender + { "DIRT" }, // Dirty Drunk + { "SHOU" }, // Shouting Drunk + { "STAG" }, // Staggering Drunk + { "BOUN" }, // Bouncer + { "SAND" }, // James Sanders - At Home + { "CORO" }, // The Coroner + { "EQUE" }, // The Equestrian Shop Keeper + { "GEOR" }, // George Blackwood + { "LARS" }, // Lars + { "PARK" }, // Sheila Parker (happy) + { "CHEM" }, // Chemist + { "GREG" }, // Inspector Gregson + { "LAWY" }, // Jacob Farthington Lawyer + { "MYCR" }, // Mycroft + { "SHER" }, // Old Sherman + { "CHMB" }, // Richard Chemist Stock boy + { "BARM" }, // Barman + { "DAND" }, // Dandy Player + { "ROUG" }, // Rough-looking Player + { "SPEC" }, // Spectator + { "HUNT" }, // Robert Hunt + { "VIOL" }, // Violet Secretary + { "PETT" }, // Pettigrew + { "APPL" }, // Augie (apple seller) + { "ANNA" }, // Anna Carroway + { "GUAR" }, // Guard + { "ANTO" }, // Antonio Caruso + { "TOBY" }, // Toby the Dog + { "KING" }, // Simon Kingsley + { "ALFR" }, // Alfred Tobacco Clerk + { "LADY" }, // Lady Brumwell + { "ROSA" }, // Madame Rosa + { "LADB" }, // Lady Brumwell + { "MOOR" }, // Joseph Moorehead + { "BEAL" }, // Mrs. Beale + { "LION" }, // Felix the Lion + { "HOLL" }, // Hollingston + { "CALL" }, // Constable Callaghan + { "JERE" }, // Sergeant Jeremy Duncan + { "LORD" }, // Lord Brumwell + { "NIGE" }, // Nigel Jameson + { "JONA" }, // Jonas (newspaper seller) + { "DUGA" }, // Constable Dugan + { "INSP" } // Inspector Lestrade (Scotland Yard) +}; + +const char *const NAMES[MAX_PEOPLE] = { + "Sherlock Holmes", + "Dr. Watson", + "Inspector Lestrade", + "Constable O'Brien", + "Constable Lewis", + "Sheila Parker", + "Henry Carruthers", + "Lesley", + "An Usher", + "An Usher", + "Fredrick Epstein", + "Mrs. Worthington", + "The Coach", + "A Player", + "Tim", + "James Sanders", + "Belle", + "Cleaning Girl", + "Fredrick Epstein", + "Wiggins", + "Paul", + "The Bartender", + "A Dirty Drunk", + "A Shouting Drunk", + "A Staggering Drunk", + "The Bouncer", + "James Sanders", + "The Coroner", + "Reginald Snipes", + "George Blackwood", + "Lars", + "Sheila Parker", + "The Chemist", + "Inspector Gregson", + "Jacob Farthington", + "Mycroft", + "Old Sherman", + "Richard", + "The Barman", + "A Dandy Player", + "A Rough-looking Player", + "A Spectator", + "Robert Hunt", + "Violet", + "Pettigrew", + "Augie", + "Anna Carroway", + "A Guard", + "Antonio Caruso", + "Toby the Dog", + "Simon Kingsley", + "Alfred", + "Lady Brumwell", + "Madame Rosa", + "Lady Brumwell", + "Joseph Moorehead", + "Mrs. Beale", + "Felix", + "Hollingston", + "Constable Callaghan", + "Sergeant Duncan", + "Lord Brumwell", + "Nigel Jaimeson", + "Jonas", + "Constable Dugan", + "Inspector Lestrade" +}; + +/*----------------------------------------------------------------*/ People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) { _walkLoaded = false; @@ -63,6 +202,7 @@ People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) { _talkPics = nullptr; _portraitSide = 0; _speakerFlip = false; + _holmesFlip = false; } People::~People() { @@ -439,6 +579,27 @@ void People::goAllTheWay() { } } +/** + * Finds the scene background object corresponding to a specified speaker + */ +int People::findSpeaker(int speaker) { + Scene &scene = *_vm->_scene; + + for (int idx = 0; idx < (int)scene._bgShapes.size(); ++idx) { + Object &obj = scene._bgShapes[idx]; + + if (obj._type == ACTIVE_BG_SHAPE) { + Common::String name(obj._name.c_str(), obj._name.c_str() + 4); + + if (scumm_stricmp(PORTRAITS[speaker], name.c_str()) == 0 + && obj._name[4] >= '0' && obj._name[4] <= '9') + return idx - 1; + } + } + + return -1; +} + /** * Turn off any currently active portraits, and removes them from being drawn */ @@ -472,9 +633,65 @@ void People::clearTalking() { } } -int People::findSpeaker(int speaker) { - // TODO - return -1; +/** + * Setup the data for an animating speaker portrait at the top of the screen + */ +void People::setTalking(int speaker) { + Resources &res = *_vm->_res; + + // If no speaker is specified, then we can exit immediately + if (speaker == -1) + return; + + if (_portraitsOn) { + delete _talkPics; + _talkPics = new ImageFile("portrait.lib"); + + // Load portrait sequences + Common::SeekableReadStream *stream = res.load("sequence.txt"); + stream->seek(speaker * MAX_FRAME); + + int idx = 0; + do { + _portrait._sequences[idx] = stream->readByte(); + ++idx; + } while (idx < 2 || _portrait._sequences[idx - 2] || _portrait._sequences[idx - 1]); + + delete stream; + + _portrait._maxFrames = idx; + _portrait._frameNumber = 0; + _portrait._sequenceNumber = 0; + _portrait._images = _talkPics; + _portrait._imageFrame = &(*_talkPics)[0]; + _portrait._position = Common::Point(_portraitSide, 10); + _portrait._delta = Common::Point(0, 0); + _portrait._oldPosition = Common::Point(0, 0); + _portrait._goto = Common::Point(0, 0); + _portrait._flags = 5; + _portrait._status = 0; + _portrait._misc = 0; + _portrait._allow = 0; + _portrait._type = ACTIVE_BG_SHAPE; + _portrait._name = " "; + _portrait._description = " "; + _portrait._examine = " "; + _portrait._walkCount = 0; + + if (_holmesFlip || _speakerFlip) { + _portrait._flags |= 2; + + _holmesFlip = false; + _speakerFlip = false; + } + + if (_portraitSide == 20) + _portraitSide = 220; + else + _portraitSide = 20; + + _portraitLoaded = true; + } } } // End of namespace Sherlock diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index 1a846dded1..bec078d11e 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -34,7 +34,7 @@ enum PeopleId { PLAYER = 0, AL = 0, PEG = 1, - MAX_PEOPLE = 2 + MAX_PEOPLE = 66 }; // Animation sequence identifiers for characters @@ -66,8 +66,8 @@ private: bool _walkLoaded; int _oldWalkSequence; int _srcZone, _destZone; - ImageFile *_talkPics; public: + ImageFile *_talkPics; Common::Point _walkDest; Common::Stack _walkTo; Person &_player; @@ -79,6 +79,7 @@ public: bool _allowWalkAbort; int _portraitSide; bool _speakerFlip; + bool _holmesFlip; public: People(SherlockEngine *vm); ~People(); @@ -102,9 +103,10 @@ public: void goAllTheWay(); - void clearTalking(); - int findSpeaker(int speaker); + + void clearTalking(); + void setTalking(int speaker); }; } // End of namespace Sherlock diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 193c0f9a19..c97f2a0646 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -161,7 +161,6 @@ void Talk::talkTo(const Common::String &filename) { Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; Scripts &scripts = *_vm->_scripts; - Talk &talk = *_vm->_talk; UserInterface &ui = *_vm->_ui; Common::Rect savedBounds = screen.getDisplayBounds(); bool abortFlag = false; @@ -202,10 +201,10 @@ void Talk::talkTo(const Common::String &filename) { people.gotoStand(people._player); } - if (talk._talkToAbort) + if (_talkToAbort) return; - talk.freeTalkVars(); + freeTalkVars(); // If any sequences have changed in the prior talk file, restore them if (_savedSequences.size() > 0) { @@ -928,8 +927,36 @@ void Talk::pushSequence(int speaker) { error("script stack overflow"); } +/** + * Change the sequence of the scene background object associated with the current speaker. + */ void Talk::setSequence(int speaker) { - // TODO + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + + // If no speaker is specified, then nothing needs to be done + if (speaker != -1) + return; + + if (speaker) { + int objNum = people.findSpeaker(speaker); + if (objNum != -1) { + Object &obj = scene._bgShapes[objNum]; + + if (obj._seqSize < MAX_TALK_SEQUENCES) { + warning("Tried to copy too many talk frames"); + } else { + for (int idx = 0; idx < MAX_TALK_SEQUENCES; ++idx) { + obj._sequences[idx] = TALK_SEQUENCES[speaker][idx]; + if (idx > 0 && !TALK_SEQUENCES[speaker][idx] && !TALK_SEQUENCES[speaker][idx - 1]) + return; + + obj._frameNumber = 0; + obj._sequenceNumber = 0; + } + } + } + } } /** @@ -1045,7 +1072,7 @@ void Talk::doScript(const Common::String &script) { } else { // Nope, so set the first speaker - setTalking(_speaker); + people.setTalking(_speaker); } } @@ -1068,7 +1095,7 @@ void Talk::doScript(const Common::String &script) { _scriptCurrentIndex = str - script.c_str(); if (!(_speaker & 128)) - clearTalking(); + people.clearTalking(); if (_talkToAbort) return; @@ -1077,7 +1104,7 @@ void Talk::doScript(const Common::String &script) { charCount = line = 0; _speaker = *++str - 1; - setTalking(_speaker); + people.setTalking(_speaker); pullSequence(); pushSequence(_speaker); setSequence(_speaker); @@ -1128,7 +1155,7 @@ void Talk::doScript(const Common::String &script) { _scriptCurrentIndex = str - script.c_str(); if (_speaker < 128) - clearTalking(); + people.clearTalking(); pullSequence(); if (_talkToAbort) return; @@ -1214,7 +1241,7 @@ void Talk::doScript(const Common::String &script) { _scriptCurrentIndex = str - script.c_str(); if (!(_speaker & 128)) - clearTalking(); + people.clearTalking(); pullSequence(); if (_talkToAbort) @@ -1426,11 +1453,13 @@ void Talk::doScript(const Common::String &script) { case WALK_TO_CANIMATION: { ++str; - int animIndex = str[0] - 1; + CAnim &anim = scene._cAnim[str[0] - 1]; // Save the current point in the script, since it might be intterupted by // doing bg anims in the next call, so we need to know where to return to _scriptCurrentIndex = (str + 1) - script.c_str(); + + people.walkToCoords(anim._goto, anim._gotoDir); if (_talkToAbort) return; break; @@ -1616,18 +1645,10 @@ void Talk::doScript(const Common::String &script) { pullSequence(); if (_speaker < 128) - clearTalking(); + people.clearTalking(); } } -void Talk::clearTalking() { - // TODO -} - -void Talk::setTalking(int speaker) { - // TODO -} - /** * When the talk window has been displayed, waits a period of time proportional to * the amount of text that's been displayed diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index 1b679a47bd..1a7dd587da 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -110,9 +110,6 @@ private: void doScript(const Common::String &script); - void clearTalking(); - void setTalking(int speaker); - int waitForMore(int delay); public: bool _talkToAbort; -- cgit v1.2.3 From 0f0321eb43fa321319805db8264601d0f2646282 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 11 Apr 2015 17:50:07 -0500 Subject: SHERLOCK: Fix startup initialization --- engines/sherlock/talk.cpp | 9 +++++++-- engines/sherlock/user_interface.cpp | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index c97f2a0646..ec3f67bd84 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -134,7 +134,7 @@ Talk::Talk(SherlockEngine *vm): _vm(vm) { _talkStealth = 0; _talkToFlag = -1; _moreTalkDown = _moreTalkUp = false; - _scriptMoreFlag = 1; + _scriptMoreFlag = false; _scriptSaveIndex = -1; _scriptCurrentIndex = -1; } @@ -683,7 +683,7 @@ void Talk::drawInterface() { int strWidth = screen.stringWidth(PRESS_KEY_TO_CONTINUE); screen.makeButton(Common::Rect(46, CONTROLS_Y, 273, CONTROLS_Y + 10), 160 - strWidth, PRESS_KEY_TO_CONTINUE); - screen.gPrint(Common::Point(160 - strWidth / 2, CONTROLS_Y), COMMAND_FOREGROUND, false, "P"); + screen.gPrint(Common::Point(160 - strWidth / 2, CONTROLS_Y), COMMAND_FOREGROUND, "P"); } } @@ -880,6 +880,9 @@ void Talk::clearSequences() { void Talk::pullSequence() { Scene &scene = *_vm->_scene; + if (_scriptStack.empty()) + return; + SequenceEntry seq = _scriptStack.pop(); if (seq._objNum != -1) { Object &obj = scene._bgShapes[seq._objNum]; @@ -1518,6 +1521,8 @@ void Talk::doScript(const Common::String &script) { int width = 0, idx = 0; do { width += screen.charWidth(str[idx]); + ++idx; + ++charCount; } while (width < 298 && str[idx] && str[idx] != '{' && str[idx] < 128); if (str[idx] || width >= 298) { diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 88265f6a19..2b808a085a 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -86,6 +86,8 @@ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { _find = 0; _oldUse = 0; _endKeyActive = true; + _lookScriptFlag = false; + _infoFlag = false; } UserInterface::~UserInterface() { -- cgit v1.2.3 From 461d5c64f27c2cf86890a9ba8d7df8a63f6278e7 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 11 Apr 2015 23:42:11 -0500 Subject: SHERLOCK: Fixes for opening door --- engines/sherlock/objects.cpp | 40 ++++++-- engines/sherlock/objects.h | 8 +- engines/sherlock/people.h | 15 ++- engines/sherlock/scene.cpp | 15 ++- engines/sherlock/talk.cpp | 2 +- engines/sherlock/user_interface.cpp | 197 +++++++++++++++++++++++++++++++++++- engines/sherlock/user_interface.h | 1 + 7 files changed, 254 insertions(+), 24 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index e4730ef207..dc57322bd4 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -248,7 +248,7 @@ void Sprite::checkSprite() { case TALK: case TALK_EVERY: - _type = HIDDEN; + obj._type = HIDDEN; obj.setFlagsAndToggles(); talk.talkTo(obj._use[0]._target); break; @@ -400,6 +400,36 @@ void Object::setVm(SherlockEngine *vm) { _countCAnimFrames = false; } +Object::Object() { + _sequenceOffset = 0; + _sequences = nullptr; + _images = nullptr; + _imageFrame = nullptr; + _walkCount = 0; + _allow = 0; + _frameNumber = 0; + _sequenceNumber = 0; + _type = INVALID; + _pickup = 0; + _defaultCommand = 0; + _lookFlag = 0; + _pickupFlag = 0; + _requiredFlag = 0; + _status = 0; + _misc = 0; + _maxFrames = 0; + _flags = 0; + _lookFrames = 0; + _seqCounter = 0; + _lookFacing = 0; + _lookcAnim = 0; + _seqStack = 0; + _seqTo = 0; + _descOffset = 0; + _seqCounter2 = 0; + _seqSize = 0; +} + /** * Load the object data from the passed stream */ @@ -770,7 +800,7 @@ void Object::setObjSequence(int seq, bool wait) { * @param messages Provides a lookup list of messages that can be printed * @returns 0 if no codes are found, 1 if codes were found */ -int Object::checkNameForCodes(const Common::String &name, Common::StringArray *messages) { +int Object::checkNameForCodes(const Common::String &name, const char *const messages[]) { People &people = *_vm->_people; Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; @@ -851,15 +881,13 @@ int Object::checkNameForCodes(const Common::String &name, Common::StringArray *m int messageNum = atoi(name.c_str() + 1); ui._infoFlag++; ui.clearInfo(); - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, - (*messages)[messageNum].c_str()); + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, messages[messageNum]); ui._menuCounter = 25; } else if (name.hasPrefix("@")) { // Message attached to canimation ui._infoFlag++; ui.clearInfo(); - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, - "%s", name.c_str() + 1); + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, name.c_str() + 1); printed = true; ui._menuCounter = 25; } diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 26ad1d3900..2c642b5a58 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -34,7 +34,7 @@ namespace Sherlock { class SherlockEngine; enum ObjectAllow { - ALLOW_MOVEMENT = 1, ALLOW_OPEN = 2, ALLOW_CLOSE = 4 + ALLOW_MOVE = 1, ALLOW_OPEN = 2, ALLOW_CLOSE = 4 }; enum SpriteType { @@ -122,6 +122,8 @@ public: int frameHeight() const { return _imageFrame ? _imageFrame->_frame.h : 0; } }; +enum { REVERSE_DIRECTION = 0x80 }; + struct ActionType { int8 _cAnimNum; uint8 _cAnimSpeed; // if high bit set, play in reverse @@ -198,13 +200,15 @@ public: ActionType _aMove; UseType _use[4]; + Object(); + void synchronize(Common::SeekableReadStream &s); void toggleHidden(); void checkObject(Object &o); - int checkNameForCodes(const Common::String &name, Common::StringArray *messages); + int checkNameForCodes(const Common::String &name, const char *const messages[]); void setFlagsAndToggles(); diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index bec078d11e..ba870d041d 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -34,7 +34,8 @@ enum PeopleId { PLAYER = 0, AL = 0, PEG = 1, - MAX_PEOPLE = 66 + NUM_OF_PEOPLE = 2, // Holmes and Watson + MAX_PEOPLE = 66 // Total of all NPCs }; // Animation sequence identifiers for characters @@ -62,7 +63,7 @@ public: class People { private: SherlockEngine *_vm; - Person _data[MAX_PEOPLE]; + Person _data[NUM_OF_PEOPLE]; bool _walkLoaded; int _oldWalkSequence; int _srcZone, _destZone; @@ -84,8 +85,14 @@ public: People(SherlockEngine *vm); ~People(); - Person &operator[](PeopleId id) { return _data[id]; } - Person &operator[](int idx) { return _data[idx]; } + Person &operator[](PeopleId id) { + assert(id < NUM_OF_PEOPLE); + return _data[id]; + } + Person &operator[](int idx) { + assert(idx < NUM_OF_PEOPLE); + return _data[idx]; + } bool isHolmesActive() const { return _walkLoaded && _holmesOn; } diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 3d5f566164..1cad2506e5 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -314,8 +314,8 @@ bool Scene::loadScene(const Common::String &filename) { for (uint idx = 0; idx < _zones.size(); ++idx) { _zones[idx].left = boundsStream->readSint16LE(); _zones[idx].top = boundsStream->readSint16LE(); - _zones[idx].setWidth(boundsStream->readSint16LE()); - _zones[idx].setHeight(boundsStream->readSint16LE()); + _zones[idx].setWidth(boundsStream->readSint16LE() + 1); + _zones[idx].setHeight(boundsStream->readSint16LE() + 1); boundsStream->skip(2); // Skip unused scene number field } @@ -925,20 +925,18 @@ int Scene::startCAnim(int cAnimNum, int playRate) { rrmStream->seek(rrmStream->readUint32LE()); // Load the canimation into the cache - Common::SeekableReadStream *imgStream = !_lzwMode ? rrmStream : + Common::SeekableReadStream *imgStream = !_lzwMode ? rrmStream->readStream(cAnim._size) : decompressLZ(*rrmStream, cAnim._size); res.addToCache(fname, *imgStream); - if (_lzwMode) - delete imgStream; - + delete imgStream; delete rrmStream; } // Now load the resource as an image - cObj._maxFrames = cObj._images->size(); cObj._images = new ImageFile(fname); cObj._imageFrame = &(*cObj._images)[0]; + cObj._maxFrames = cObj._images->size(); int frames = 0; if (playRate < 0) { @@ -946,8 +944,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) { // Count number of frames while (cObj._sequences[frames] && frames < MAX_FRAME) ++frames; - } - else { + } else { // Forward direction Object::_countCAnimFrames = true; diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index ec3f67bd84..281b6b4672 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -583,7 +583,7 @@ void Talk::loadTalkFile(const Common::String &filename) { // Check for an existing person being talked to _talkTo = -1; - for (int idx = 0; idx < MAX_PEOPLE; ++idx) { + for (int idx = 0; idx < NUM_OF_PEOPLE; ++idx) { if (!scumm_strnicmp(filename.c_str(), people[(PeopleId)idx]._portrait.c_str(), 4)) { _talkTo = idx; break; diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 2b808a085a..ebbe00ffbc 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -58,6 +58,25 @@ const char INVENTORY_COMMANDS[9] = { "ELUG-+,." }; const char *const PRESS_KEY_FOR_MORE = "Press any Key for More."; const char *const PRESS_KEY_TO_CONTINUE = "Press any Key to Continue."; +const char *const MOPEN[] = { + "This cannot be opened", "It is already open", "It is locked", "Wait for Watson", " ", "." +}; +const char *const MCLOSE[] = { + "This cannot be closed", "It is already closed", "The safe door is in the way" +}; +const char *const MMOVE[] = { + "This cannot be moved", "It is bolted to the floor", "It is too heavy", "The other crate is in the way" +}; +const char *const MPICK[] = { + "Nothing of interest here", "It is bolted down", "It is too big to carry", "It is too heavy", + "I think a girl would be more your type", "Those flowers belong to Penny", "She's far too young for you!", + "I think a girl would be more your type!", "Government property for official use only" +}; +const char *const MUSE[] = { + "You can't do that", "It had no effect", "You can't reach it", "OK, the door looks bigger! Happy?", + "Doors don't smoke" +}; + /*----------------------------------------------------------------*/ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { @@ -327,7 +346,7 @@ void UserInterface::handleInput() { break; case MOVE_MODE: - doMiscControl(ALLOW_MOVEMENT); + doMiscControl(ALLOW_MOVE); break; case TALK_MODE: @@ -1122,8 +1141,56 @@ void UserInterface::doMainControl() { } } +/** + * Handles the input for the MOVE, OPEN, and CLOSE commands + */ void UserInterface::doMiscControl(int allowed) { - // TODO + Events &events = *_vm->_events; + Scene &scene = *_vm->_scene; + Talk &talk = *_vm->_talk; + + if (events._released) { + _temp = _bgFound; + if (_bgFound != -1) { + // Only allow pointing to objects, not people + if (_bgFound < 1000) { + events.clearEvents(); + Object &obj = scene._bgShapes[_bgFound]; + + switch (allowed) { + case ALLOW_OPEN: + checkAction(obj._aOpen, MOPEN, _temp); + if (_menuMode && !talk._talkToAbort) { + _menuMode = STD_MODE; + restoreButton(OPEN_MODE - 1); + _key = _oldKey = -1; + } + break; + + case ALLOW_CLOSE: + checkAction(obj._aClose, MCLOSE, _temp); + if (_menuMode != TALK_MODE && !talk._talkToAbort) { + _menuMode = STD_MODE; + restoreButton(CLOSE_MODE - 1); + _key = _oldKey = -1; + } + break; + + case ALLOW_MOVE: + checkAction(obj._aMove, MMOVE, _temp); + if (_menuMode != TALK_MODE && !talk._talkToAbort) { + _menuMode = STD_MODE; + restoreButton(MOVE_MODE - 1); + _key = _oldKey = -1; + } + break; + + default: + break; + } + } + } + } } void UserInterface::doPickControl() { @@ -1503,5 +1570,131 @@ void UserInterface::checkUseAction(UseType &use, const Common::String &invName, // TODO } +/** + * Called for OPEN, CLOSE, and MOVE actions are being done + */ +void UserInterface::checkAction(ActionType &action, const char *const messages[], int objNum) { + Events &events = *_vm->_events; + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + Screen &screen = *_vm->_screen; + Talk &talk = *_vm->_talk; + bool printed = false; + bool doCAnim = true; + int cAnimNum; + Common::Point pt(-1, -1); + int dir = -1; + + if (objNum >= 1000) + // Ignore actions done on characters + return; + Object &obj = scene._bgShapes[objNum]; + + if (action._cAnimNum == 0) + // Really a 10 + cAnimNum = 9; + else + cAnimNum = action._cAnimNum - 1; + CAnim &anim = scene._cAnim[cAnimNum]; + + if (action._cAnimNum != 99) { + if (action._cAnimSpeed & REVERSE_DIRECTION) { + pt = anim._teleportPos; + dir = anim._teleportDir; + } else { + pt = anim._goto; + dir = anim._gotoDir; + } + } + + if (action._cAnimSpeed) { + // Has a value, so do action + // Show wait cursor whilst walking to object and doing action + events.setCursor(WAIT); + + for (int nameIdx = 0; nameIdx < 4; ++nameIdx) { + if (action._names[nameIdx].hasPrefix("*") && toupper(action._names[nameIdx][1]) == 'W') { + if (obj.checkNameForCodes(Common::String(action._names[nameIdx].c_str() + 2), messages)) { + if (!talk._talkToAbort) + printed = true; + } + } + } + + for (int nameIdx = 0; nameIdx < 4; ++nameIdx) { + if (action._names[nameIdx].hasPrefix("*")) { + char ch = toupper(action._names[nameIdx][1]); + + if (ch == 'T' || ch == 'B') { + printed = true; + if (pt.x != -1) + // Holmes needs to walk to object before the action is done + people.walkToCoords(pt, dir); + + if (!talk._talkToAbort) { + // Ensure Holmes is on the exact intended location + people[AL]._position = pt; + people[AL]._sequenceNumber = dir; + people.gotoStand(people[AL]); + + talk.talkTo(action._names[nameIdx] + 2); + if (ch == 'T') + doCAnim = false; + } + } + } + } + + if (doCAnim && !talk._talkToAbort) { + if (pt.x != -1) + // Holmes needs to walk to object before the action is done + people.walkToCoords(pt, dir); + } + + for (int nameIdx = 0; nameIdx < 4; ++nameIdx) { + if (action._names[nameIdx].hasPrefix("*") && toupper(action._names[nameIdx][1]) == 'F') { + if (obj.checkNameForCodes(action._names[nameIdx].c_str() + 2, messages)) { + if (!talk._talkToAbort) + printed = true; + } + } + } + + if (doCAnim && !talk._talkToAbort && action._cAnimNum != 99) + scene.startCAnim(cAnimNum, action._cAnimSpeed); + + if (!talk._talkToAbort) { + for (int nameIdx = 0; nameIdx < 4 && !talk._talkToAbort; ++nameIdx) { + if (obj.checkNameForCodes(action._names[nameIdx], messages)) { + if (!talk._talkToAbort) + printed = true; + } + } + + // Unless we're leaving the scene, print a "Done" message unless the printed flag has been set + if (scene._goToScene != 1 && !printed && !talk._talkToAbort) { + _infoFlag = true; + clearInfo(); + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, messages[action._cAnimNum]); + + // Set how long to show the message + _menuCounter = 30; + } + } + } else { + // Invalid action, to print error message + _infoFlag = true; + clearInfo(); + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, messages[action._cAnimNum]); + _infoFlag = true; + + // Set how long to show the message + _menuCounter = 30; + } + + // Reset cursor back to arrow + events.setCursor(ARROW); +} + } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index f80fe48b2d..9b104465cf 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -117,6 +117,7 @@ private: void checkUseAction(UseType &use, const Common::String &invName, const Common::String &msg, int objNum, int giveMode); + void checkAction(ActionType &action, const char *const messages[], int objNum); public: MenuMode _menuMode; int _menuCounter; -- cgit v1.2.3 From 454b6a2bbe38a4540769ad5cf51290b7a19524e4 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 12 Apr 2015 11:06:25 -0500 Subject: SHERLOCK: Implemented pick up code --- engines/sherlock/inventory.h | 3 +- engines/sherlock/objects.cpp | 91 +++++++++++++++++++++++++++++++++++++ engines/sherlock/objects.h | 2 + engines/sherlock/user_interface.cpp | 27 ++++++++++- engines/sherlock/user_interface.h | 1 + 5 files changed, 121 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index 436d2bc18d..4e426beaf4 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -62,8 +62,6 @@ class Inventory : public Common::Array { private: SherlockEngine *_vm; - int putItemInInventory(Object &obj); - void copyToInventory(Object &obj); public: ImageFile *_invShapes[MAX_VISIBLE_INVENTORY]; @@ -98,6 +96,7 @@ public: void doInvJF(); int putNameInInventory(const Common::String &name); + int putItemInInventory(Object &obj); int deleteItemFromInventory(const Common::String &name); }; diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index dc57322bd4..cab35f9634 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -947,6 +947,97 @@ void Object::adjustObject() { } } +/** + * Handles trying to pick up an object. If allowed, plays an y necessary animation for picking + * up the item, and then adds it to the player's inventory + */ +int Object::pickUpObject(const char *const messages[]) { + Inventory &inv = *_vm->_inventory; + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + Screen &screen = *_vm->_screen; + Talk &talk = *_vm->_talk; + UserInterface &ui = *_vm->_ui; + int pickup = _pickup & 0x7f; + bool printed = false; + bool takeFlag = true; + int numObjects = 0; + int message; + + if (pickup == 99) { + for (int idx = 0; idx < 4 && !talk._talkToAbort; ++idx) { + if (checkNameForCodes(_use[0]._names[idx], nullptr)) { + if (!talk._talkToAbort) + printed = true; + } + } + + return 0; + } + + if (!pickup || (pickup > 50 && pickup <= 80)) { + int message = _pickup; + if (message > 50) + message -= 50; + + ++ui._infoFlag; + ui.clearInfo(); + screen.print(Common::Point(0, INFO_LINE + 1), INFO_LINE, messages[message]); + ui._menuCounter = 30; + } else { + // Pick it up + if ((_pickup & 0x80) == 0) { + // Play an animation + if (pickup > 80) { + takeFlag = false; // Don't pick it up + scene.startCAnim(pickup - 81, 1); + if (_pickupFlag) + _vm->setFlags(_pickupFlag); + } else { + scene.startCAnim(pickup - 1, 1); + if (!talk._talkToAbort) { + // Erase the shape + _type = _type == NO_SHAPE ? INVALID : REMOVE; + } + } + + if (talk._talkToAbort) + return 0; + } else { + // Play generic pickup sequence + // Original moved cursor position here + people.goAllTheWay(); + ui._menuCounter = 25; + ui._temp1 = 1; + } + + for (int idx = 0; idx < 4 && !talk._talkToAbort; ++idx) { + if (checkNameForCodes(_use[0]._names[idx], nullptr)) { + if (!talk._talkToAbort) + printed = true; + } + } + if (talk._talkToAbort) + return 0; + + // Add the item to the player's inventory + if (takeFlag) + numObjects = inv.putItemInInventory(*this); + + if (!printed) { + ui._infoFlag++; + ui.clearInfo(); + + Common::String itemName = _description; + itemName.setChar(tolower(itemName[0]), 0); + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "Picked up %s", itemName.c_str()); + ui._menuCounter = 25; + } + } + + return numObjects; +} + /** * Returns the current bounds for the sprite */ diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 2c642b5a58..534ed66643 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -214,6 +214,8 @@ public: void adjustObject(); + int pickUpObject(const char *const messages[]); + int frameWidth() const { return _imageFrame ? _imageFrame->_frame.w : 0; } int frameHeight() const { return _imageFrame ? _imageFrame->_frame.h : 0; } const Common::Rect getNewBounds() const; diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index ebbe00ffbc..9104c761a0 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -92,6 +92,7 @@ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { _lookHelp = 0; _key = _oldKey = 0; _temp = _oldTemp = 0; + _temp1 = 0; _invLookFlag = 0; _windowOpen = false; _oldLook = false; @@ -711,6 +712,9 @@ void UserInterface::lookInv() { } } +/** + * Handles input when the file list window is being displayed + */ void UserInterface::doEnvControl() { // TODO } @@ -1193,8 +1197,29 @@ void UserInterface::doMiscControl(int allowed) { } } +/** + * Handles input for picking up items + */ void UserInterface::doPickControl() { - // TODO + Events &events = *_vm->_events; + Scene &scene = *_vm->_scene; + + if (events._released) { + if ((_temp = _bgFound) != -1) { + events.clearEvents(); + + // Don't allow characters to be picked up + if (_bgFound < 1000) { + scene._bgShapes[_bgFound].pickUpObject(MPICK); + + if (_menuMode != TALK_MODE) { + _key = _oldKey = -1; + _menuMode = STD_MODE; + restoreButton(PICKUP_MODE - 1); + } + } + } + } } void UserInterface::doTalkControl() { diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index 9b104465cf..c4a07abc76 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -125,6 +125,7 @@ public: bool _windowOpen; bool _endKeyActive; int _invLookFlag; + int _temp1; public: UserInterface(SherlockEngine *vm); ~UserInterface(); -- cgit v1.2.3 From c9890cbacc7bf6a1216cadf6eddc04832f0ebbe4 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 12 Apr 2015 17:55:55 -0500 Subject: SHERLOCK: Implementing event handling for talk display --- engines/sherlock/people.cpp | 1 + engines/sherlock/people.h | 1 + engines/sherlock/talk.h | 4 +- engines/sherlock/user_interface.cpp | 254 +++++++++++++++++++++++++++++++++++- 4 files changed, 258 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 5c7f9ef506..e6a4eeed0f 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -203,6 +203,7 @@ People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) { _portraitSide = 0; _speakerFlip = false; _holmesFlip = false; + _homesQuotient = 0; } People::~People() { diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index ba870d041d..601fe6006b 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -81,6 +81,7 @@ public: int _portraitSide; bool _speakerFlip; bool _holmesFlip; + int _homesQuotient; public: People(SherlockEngine *vm); ~People(); diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index 1a7dd587da..c4b5fe46d2 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -79,8 +79,10 @@ struct TalkSequences { }; class SherlockEngine; +class UserInterface; class Talk { + friend class UserInterface; private: Common::Array STILL_SEQUENCES; Common::Array TALK_SEQUENCES; @@ -97,7 +99,6 @@ private: int _converseNum; int _talkStealth; int _talkToFlag; - bool _moreTalkUp, _moreTalkDown; int _scriptSaveIndex; int _scriptCurrentIndex; private: @@ -117,6 +118,7 @@ public: int _talkTo; int _scriptMoreFlag; Common::String _scriptName; + bool _moreTalkUp, _moreTalkDown; public: Talk(SherlockEngine *vm); void setSequences(const byte *talkSequences, const byte *stillSequences, diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 9104c761a0..70f284c359 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1222,8 +1222,260 @@ void UserInterface::doPickControl() { } } +/** + * Handles input when in talk mode. It highlights the buttons and available statements, + * and handles allowing the user to click on them + */ void UserInterface::doTalkControl() { - // TODO + Events &events = *_vm->_events; + Journal &journal = *_vm->_journal; + People &people = *_vm->_people; + Screen &screen = *_vm->_screen; + Sound &sound = *_vm->_sound; + Talk &talk = *_vm->_talk; + UserInterface &ui = *_vm->_ui; + Common::Point mousePos = events.mousePos(); + int select; + + _key = _oldKey = -1; + _keyboardInput = false; + + if (events._pressed || events._released) { + events.clearKeyboard(); + + // Handle button printing + if (mousePos.x > 99 && mousePos.x < 138 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 10) && !_endKeyActive) + screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Exit"); + else if (_endKeyActive) + screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_FOREGROUND, true, "Exit"); + + if (mousePos.x > 140 && mousePos.x < 170 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 10) && talk._moreTalkUp) + screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Up"); + else if (talk._moreTalkUp) + screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_FOREGROUND, true, "Up"); + + if (mousePos.x > 181&& mousePos.x < 220 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 10) && talk._moreTalkDown) + screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Down"); + else if (talk._moreTalkDown) + screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_FOREGROUND, true, "Down"); + + bool found = false; + for (_selector = talk._talkIndex; _selector < (int)talk._statements.size() && !found; ++_selector) { + if (mousePos.y > talk._statements[_selector]._talkPos.top && + mousePos.y < talk._statements[_selector]._talkPos.bottom) + found = true; + } + --_selector; + if (!found) + _selector = -1; + } + + if (_keycode != Common::KEYCODE_INVALID) { + _key = toupper(_keycode); + if (_key == Common::KEYCODE_ESCAPE) + _key = 'E'; + + // Check for number press indicating reply line + if (_key >= '1' && _key <= ('1' + (int)talk._statements.size() - 1)) { + for (uint idx = 0; idx < talk._statements.size(); ++idx) { + if (talk._statements[idx]._talkMap == (_key - '1')) { + // Found the given statement + _selector = idx; + _key = -1; + _keyboardInput = true; + break; + } + } + } else if (_key == 'E' || _key == 'U' || _key == 'D') { + _keyboardInput = true; + } else { + _selector = -1; + } + } + + if (_selector != _oldSelector) { + // Remove highlighting from previous line, if any + if (_oldSelector != -1) { + if (!((talk._talkHistory[talk._converseNum][_oldSelector] >> (_oldSelector & 7)) & 1)) + talk.talkLine(_oldSelector, talk._statements[_oldSelector]._talkMap, INV_FOREGROUND, + talk._statements[_oldSelector]._talkPos.top, true); + else + talk.talkLine(_oldSelector, talk._statements[_oldSelector]._talkMap, TALK_NULL, + talk._statements[_oldSelector]._talkPos.top, true); + } + + // Add highlighting to new line, if any + if (_selector != -1) + talk.talkLine(_selector, talk._statements[_selector]._talkMap, TALK_FOREGROUND, + talk._statements[_selector]._talkPos.top, true); + } + + if (events._released || _keyboardInput) { + if (_endKeyActive && ((mousePos.x > 99 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 10) + && talk._moreTalkUp && events._released) || _key == 'E')) { + talk.freeTalkVars(); + talk.pullSequence(); + banishWindow(); + _windowBounds.top = CONTROLS_Y1; + } else if ((mousePos.x > 140 && mousePos.x < 179 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 10) + && talk._moreTalkUp && events._released) || (talk._moreTalkUp && _key == 'U')) { + while (talk._statements[--talk._talkIndex]._talkMap == -1) + ; + screen._backBuffer1.fillRect(Common::Rect(5, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, + SHERLOCK_SCREEN_HEIGHT - 1), INV_BACKGROUND); + talk.displayTalk(false); + + screen.slamRect(Common::Rect(5, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH - 5, SHERLOCK_SCREEN_HEIGHT - 2)); + } else if ((mousePos.x > 181 && mousePos.x < 220 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 10) + && talk._moreTalkDown && events._released) || (talk._moreTalkDown && _key == 'D')) { + do { + ++talk._talkIndex; + } while (talk._talkIndex < (int)talk._statements.size() && talk._statements[talk._talkIndex]._talkMap == -1); + + screen._backBuffer1.fillRect(Common::Rect(5, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, + SHERLOCK_SCREEN_HEIGHT - 1), INV_BACKGROUND); + talk.displayTalk(false); + + screen.slamRect(Common::Rect(5, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH - 5, SHERLOCK_SCREEN_HEIGHT - 2)); + } else if (_selector != -1) { + screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_NULL, true, "Exit"); + screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_NULL, true, "Up"); + screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, true, "Down"); + + // If the reply is new, add it to the journal + if (!talk._talkHistory[talk._converseNum][_selector]) { + journal.record(talk._converseNum, _selector); + + // Add any Holmes point to Holmes' total, if any + if (talk._statements[_selector]._quotient) + people._homesQuotient += talk._statements[_selector]._quotient; + } + + // Flag the response as having been used + talk._talkHistory[talk._converseNum][_selector] = true; + + clearWindow(); + screen.print(Common::Point(16, CONTROLS_Y + 12), TALK_FOREGROUND, "Sherlock Holmes"); + talk.talkLine(_selector + 128, talk._statements[_selector]._talkMap, COMMAND_FOREGROUND, CONTROLS_Y + 21, true); + + switch (talk._statements[_selector]._portraitSide & 3) { + case 0: + case 1: + people._portraitSide = 20; + break; + case 2: + people._portraitSide = 220; + break; + case 3: + people._portraitSide = 120; + break; + } + + // Check for flipping Holmes + if (talk._statements[_selector]._portraitSide & REVERSE_DIRECTION) + people._holmesFlip = true; + + talk._speaker = 0; + people.setTalking(0); + + if (!talk._statements[_selector]._voiceFile.empty() && sound._voices) { + sound.playSound(talk._statements[_selector]._voiceFile); + + // Set voices as an indicator for waiting + sound._voices = 2; + sound._speechOn = *sound._soundIsOn; + } else { + sound._speechOn = false; + } + + // Set the _scriptCurrentIndex so if the statement is irrupted, the entire + // reply will be shown when it's restarted + talk._scriptCurrentIndex = 0; + talk.waitForMore(talk._statements[_selector]._statement.size()); + if (talk._talkToAbort) + return; + + people.clearTalking(); + if (talk._talkToAbort) + return; + + while (!_vm->shouldQuit()) { + talk._scriptSelect = _selector; + talk._speaker = talk._talkTo; + talk.doScript(talk._statements[_selector]._reply); + + if (!talk._talkToAbort) { + if (!talk._talkStealth) + clearWindow(); + + if (!talk._statements[_selector]._modified.empty()) { + for (uint idx = 0; idx < talk._statements[_selector]._modified.size(); ++idx) { + _vm->setFlags(talk._statements[_selector]._modified[idx]); + } + + talk.setTalkMap(); + } + + // Check for another linked talk file + Common::String linkFilename = talk._statements[_selector]._linkFile; + if (!linkFilename.empty() && !talk._scriptMoreFlag) { + talk.freeTalkVars(); + talk.loadTalkFile(linkFilename); + + // Find the first new statement + select = _selector = _oldSelector = -1; + for (uint idx = 0; idx < talk._statements.size() && select == -1; ++idx) { + if (!talk._statements[idx]._talkMap) + select = talk._talkIndex = idx; + } + + // See if the new statement is a stealth reply + talk._talkStealth = talk._statements[select]._statement.hasPrefix("^") ? 2 : 0; + + // Is the new talk file a standard file, reply first file, or a stealth file + if (!talk._statements[select]._statement.hasPrefix("*") && + !talk._statements[select]._statement.hasPrefix("^")) { + // Not a reply first file, so display the new selections + if (_endKeyActive) + screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_FOREGROUND, true, "Exit"); + else + screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_NULL, true, "Exit"); + + talk.displayTalk(true); + events.setCursor(ARROW); + break; + } else { + _selector = select; + + if (!talk._talkHistory[talk._converseNum][_selector]) + journal.record(talk._converseNum, _selector); + + talk._talkHistory[talk._converseNum][_selector] = true; + } + } else { + talk.freeTalkVars(); + talk.pullSequence(); + banishWindow(); + _windowBounds.top = CONTROLS_Y1; + break; + } + } else { + break; + } + } + + events._pressed = events._released = false; + events._oldButtons = 0; + talk._talkStealth = 0; + + // If a script was pushed onto the script stack, restore it + if (!talk._scriptStack.empty()) { + SequenceEntry seqEntry = talk._scriptStack.pop(); +// talk._scriptName = seqEntry. + // TODO + } + } + } } void UserInterface::journalControl() { -- cgit v1.2.3 From e8e095aa2ad7f3914b3b8dd4826c2d13e35b1163 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 12 Apr 2015 19:11:34 -0500 Subject: SHERLOCK: Fix mixups with sequence stack and script stack --- engines/sherlock/talk.cpp | 6 +++--- engines/sherlock/talk.h | 3 ++- engines/sherlock/user_interface.cpp | 8 ++++---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 281b6b4672..a40d3ace2d 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -883,7 +883,7 @@ void Talk::pullSequence() { if (_scriptStack.empty()) return; - SequenceEntry seq = _scriptStack.pop(); + SequenceEntry seq = _sequenceStack.pop(); if (seq._objNum != -1) { Object &obj = scene._bgShapes[seq._objNum]; @@ -911,7 +911,7 @@ void Talk::pushSequence(int speaker) { if (speaker == -1) return; - ScriptStackEntry seqEntry; + SequenceEntry seqEntry; if (!speaker) { seqEntry._objNum = -1; } else { @@ -925,7 +925,7 @@ void Talk::pushSequence(int speaker) { seqEntry._seqTo = obj._seqTo; } - _scriptStack.push(seqEntry); + _sequenceStack.push(seqEntry); if (_scriptStack.size() >= 5) error("script stack overflow"); } diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index c4b5fe46d2..bf4f12675c 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -40,7 +40,7 @@ struct SequenceEntry { int _seqTo; }; -struct ScriptStackEntry : public SequenceEntry { +struct ScriptStackEntry { Common::String _name; int _currentIndex; int _select; @@ -90,6 +90,7 @@ private: SherlockEngine *_vm; int _saveSeqNum; Common::Stack _savedSequences; + Common::Stack _sequenceStack; Common::Stack _scriptStack; Common::Array _statements; TalkHistoryEntry _talkHistory[500]; diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 70f284c359..e20813822e 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1233,7 +1233,6 @@ void UserInterface::doTalkControl() { Screen &screen = *_vm->_screen; Sound &sound = *_vm->_sound; Talk &talk = *_vm->_talk; - UserInterface &ui = *_vm->_ui; Common::Point mousePos = events.mousePos(); int select; @@ -1470,9 +1469,10 @@ void UserInterface::doTalkControl() { // If a script was pushed onto the script stack, restore it if (!talk._scriptStack.empty()) { - SequenceEntry seqEntry = talk._scriptStack.pop(); -// talk._scriptName = seqEntry. - // TODO + ScriptStackEntry stackEntry = talk._scriptStack.pop(); + talk._scriptName = stackEntry._name; + talk._scriptSaveIndex = stackEntry._currentIndex; + talk._scriptSelect = stackEntry._select; } } } -- cgit v1.2.3 From cf878316ea66e75b715f8467ff82594fa3a32604 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 12 Apr 2015 23:20:22 -0500 Subject: SHERLOCK: Implement settings window code --- engines/sherlock/screen.h | 2 + engines/sherlock/sherlock.cpp | 5 + engines/sherlock/sherlock.h | 4 + engines/sherlock/user_interface.cpp | 317 +++++++++++++++++++++++++++++++++++- engines/sherlock/user_interface.h | 13 ++ 5 files changed, 340 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 4e37a7787c..2cfd7c8a88 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -126,6 +126,8 @@ public: void setDisplayBounds(const Common::Rect &r); void resetDisplayBounds(); Common::Rect getDisplayBounds(); + + int fontNumber() const { return _fontNumber; } }; } // End of namespace Sherlock diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 2a1b456b76..72c072b640 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -48,6 +48,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _loadingSavedGame = false; _onChessboard = false; _slowChess = false; + _keyPadSpeed = 0; } SherlockEngine::~SherlockEngine() { @@ -177,4 +178,8 @@ void SherlockEngine::freeSaveGameList() { // TODO } +void SherlockEngine::saveConfig() { + // TODO +} + } // End of namespace Comet diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 7b562e0a23..ef10cd2d47 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -106,6 +106,8 @@ public: Common::Array _map; // Map locations for each scene bool _onChessboard; bool _slowChess; + bool _joystick; + int _keyPadSpeed; public: SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc); virtual ~SherlockEngine(); @@ -127,6 +129,8 @@ public: void setFlags(int flagNum); void freeSaveGameList(); + + void saveConfig(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index e20813822e..651844fd66 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -53,6 +53,23 @@ const int INVENTORY_POINTS[8][3] = { { 285, 315, 294 } }; +const int SETUP_POINTS[12][4] = { + { 4, 154, 101, 53 }, // Exit + { 4, 165, 101, 53 }, // Music Toggle + { 219, 165, 316, 268 }, // Voice Toggle + { 103, 165, 217, 160 }, // Sound Effects Toggle + { 219, 154, 316, 268 }, // Help Button Left/Right + { 103, 154, 217, 160 }, // New Font Style + { 4, 187, 101, 53 }, // Joystick Toggle + { 103, 187, 217, 160 }, // Calibrate Joystick + { 219, 176, 316, 268 }, // Fade Style + { 103, 176, 217, 160 }, // Window Open Style + { 4, 176, 101, 53 }, // Portraits Toggle + { 219, 187, 316, 268 } // Key Pad Accel. Toggle +}; + + + const char COMMANDS[13] = "LMTPOCIUGJFS"; const char INVENTORY_COMMANDS[9] = { "ELUG-+,." }; const char *const PRESS_KEY_FOR_MORE = "Press any Key for More."; @@ -77,6 +94,162 @@ const char *const MUSE[] = { "Doors don't smoke" }; +const char *const SETUP_STRS0[2] = { "off", "on" }; +const char *const SETUP_STRS1[2] = { "Directly", "by Pixel" }; +const char *const SETUP_STRS2[2] = { "Left", "Right" }; +const char *const SETUP_STRS3[2] = { "Appear", "Slide" }; +const char *const SETUP_STRS4[2] = { "Slow", "Fast" }; +const char *const SETUP_STRS5[2] = { "Left", "Right" }; +const char *const SETUP_NAMES[12] = { + "Exit", "M", "V", "S", "B", "New Font Style", "J", "Calibrate Joystick", "F", "W", "P", "K" +}; + +/*----------------------------------------------------------------*/ + +/** + * Draws the interface for the settings window + */ +void Settings::drawInteface(bool flag) { + People &people = *_vm->_people; + Screen &screen = *_vm->_screen; + Sound &sound = *_vm->_sound; + UserInterface &ui = *_vm->_ui; + Common::String tempStr; + + if (!flag) { + screen._backBuffer1.fillRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y1 + 1), BORDER_COLOR); + screen._backBuffer1.fillRect(Common::Rect(0, CONTROLS_Y1 + 1, 2, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); + screen._backBuffer1.fillRect(Common::Rect(SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y1 + 1, SHERLOCK_SCREEN_WIDTH, + SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); + screen._backBuffer1.hLine(0, SHERLOCK_SCREEN_HEIGHT - 1, SHERLOCK_SCREEN_WIDTH - 1, BORDER_COLOR); + screen._backBuffer1.fillRect(Common::Rect(2, CONTROLS_Y1 + 1, SHERLOCK_SCREEN_WIDTH - 2, + SHERLOCK_SCREEN_HEIGHT - 2), INV_BACKGROUND); + } + + screen.makeButton(Common::Rect(SETUP_POINTS[0][0], SETUP_POINTS[0][1], SETUP_POINTS[0][2], SETUP_POINTS[0][1] + 10), + SETUP_POINTS[0][3] - screen.stringWidth("Exit") / 2, "Exit"); + + tempStr = Common::String::format("Music %s", SETUP_STRS0[sound._music]); + screen.makeButton(Common::Rect(SETUP_POINTS[1][0], SETUP_POINTS[1][1], SETUP_POINTS[1][2], SETUP_POINTS[1][1] + 10), + SETUP_POINTS[1][3] - screen.stringWidth(tempStr) / 2, tempStr); + + tempStr = Common::String::format("Voices %s", SETUP_STRS0[sound._voices]); + screen.makeButton(Common::Rect(SETUP_POINTS[2][0], SETUP_POINTS[2][1], SETUP_POINTS[2][2], SETUP_POINTS[2][1] + 10), + SETUP_POINTS[2][3] - screen.stringWidth(tempStr) / 2, tempStr); + + tempStr = Common::String::format("Sound Effects %s", SETUP_STRS0[sound._digitized]); + screen.makeButton(Common::Rect(SETUP_POINTS[3][0], SETUP_POINTS[3][1], SETUP_POINTS[3][2], SETUP_POINTS[3][1] + 10), + SETUP_POINTS[3][3] - screen.stringWidth(tempStr) / 2, tempStr); + + tempStr = Common::String::format("Auto Help %s", SETUP_STRS5[ui._helpStyle]); + screen.makeButton(Common::Rect(SETUP_POINTS[4][0], SETUP_POINTS[4][1], SETUP_POINTS[4][2], SETUP_POINTS[4][1] + 10), + SETUP_POINTS[4][3] - screen.stringWidth(tempStr) / 2, tempStr); + screen.makeButton(Common::Rect(SETUP_POINTS[5][0], SETUP_POINTS[5][1], SETUP_POINTS[5][2], SETUP_POINTS[5][1] + 10), + SETUP_POINTS[5][3] - screen.stringWidth("New Font Style") / 2, "New Font Style"); + tempStr = Common::String::format("Joystick %s", SETUP_STRS0[_vm->_joystick ? 1 : 0]); + screen.makeButton(Common::Rect(SETUP_POINTS[6][0], SETUP_POINTS[6][1], SETUP_POINTS[6][2], SETUP_POINTS[6][1] + 10), + SETUP_POINTS[6][3] - screen.stringWidth(tempStr) / 2, tempStr); + screen.makeButton(Common::Rect(SETUP_POINTS[7][0], SETUP_POINTS[7][1], SETUP_POINTS[7][2], SETUP_POINTS[7][1] + 10), + SETUP_POINTS[7][3] - screen.stringWidth("Calibrate Joystick") / 2, "Calibrate Joystick"); + + tempStr = Common::String::format("Fade %s", screen._fadeStyle ? "by Pixel" : "Directly"); + screen.makeButton(Common::Rect(SETUP_POINTS[8][0], SETUP_POINTS[8][1], SETUP_POINTS[8][2], SETUP_POINTS[8][1] + 10), + SETUP_POINTS[8][3] - screen.stringWidth(tempStr) / 2, tempStr); + + tempStr = Common::String::format("Windows %s", ui._windowStyle ? "Slide" : "Appear"); + screen.makeButton(Common::Rect(SETUP_POINTS[9][0], SETUP_POINTS[9][1], SETUP_POINTS[9][2], SETUP_POINTS[9][1] + 10), + SETUP_POINTS[9][3] - screen.stringWidth(tempStr) / 2, tempStr); + + tempStr = Common::String::format("Portraits %s", SETUP_STRS0[people._portraitsOn]); + screen.makeButton(Common::Rect(SETUP_POINTS[10][0], SETUP_POINTS[10][1], SETUP_POINTS[10][2], SETUP_POINTS[10][1] + 10), + SETUP_POINTS[10][3] - screen.stringWidth(tempStr) / 2, tempStr); + tempStr = Common::String::format("Key Pad %s", _vm->_keyPadSpeed ? "Fast" : "Slow"); + + screen.makeButton(Common::Rect(SETUP_POINTS[11][0], SETUP_POINTS[11][1], SETUP_POINTS[11][2], SETUP_POINTS[11][1] + 10), + SETUP_POINTS[11][3] - screen.stringWidth(tempStr) / 2, tempStr); + + // Show the window immediately, or slide it on-screen + if (!flag) { + if (!ui._windowStyle) { + screen.slamRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + } else { + ui.summonWindow(true, CONTROLS_Y1); + } + + ui._windowOpen = true; + } else { + screen.slamRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + } +} + +int Settings::drawButtons(const Common::Point &pt, int key) { + Events &events = *_vm->_events; + People &people = *_vm->_people; + Screen &screen = *_vm->_screen; + Sound &sound = *_vm->_sound; + UserInterface &ui = *_vm->_ui; + int found = -1; + byte color; + Common::String tempStr; + + for (int idx = 0; idx < 12; ++idx) { + if ((pt.x > SETUP_POINTS[idx][0] && pt.x < SETUP_POINTS[idx][2] && pt.y > SETUP_POINTS[idx][1] + && pt.y < (SETUP_POINTS[idx][1] + 10) && (events._released || events._released)) + || (key == SETUP_NAMES[idx][0])) { + found = idx; + color = COMMAND_HIGHLIGHTED; + } else { + color = COMMAND_FOREGROUND; + } + + // Print the button text + switch (idx) { + case 1: + tempStr = Common::String::format("Music %s", SETUP_STRS0[sound._music]); + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); + break; + case 2: + tempStr = Common::String::format("Voices %s", SETUP_STRS0[sound._voices]); + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); + break; + case 3: + tempStr = Common::String::format("Sound Effects %s", SETUP_STRS0[sound._digitized]); + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); + break; + case 4: + tempStr = Common::String::format("Auto Help %s", SETUP_STRS2[ui._helpStyle]); + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); + break; + case 6: + tempStr = Common::String::format("Joystick %s", SETUP_STRS0[_vm->_joystick]); + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); + break; + case 8: + tempStr = Common::String::format("Fade %s", SETUP_STRS1[screen._fadeStyle]); + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); + break; + case 9: + tempStr = Common::String::format("Windows %s", SETUP_STRS3[ui._windowStyle]); + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); + break; + case 10: + tempStr = Common::String::format("Portraits %s", SETUP_STRS0[people._portraitsOn]); + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); + break; + case 11: + tempStr = Common::String::format("Key Pad %s", SETUP_STRS4[_vm->_keyPadSpeed]); + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); + break; + default: + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, SETUP_NAMES[idx]); + break; + } + } + + return found; +} + + /*----------------------------------------------------------------*/ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { @@ -1531,8 +1704,150 @@ void UserInterface::environment() { // TODO } +/** + * Handles input when the settings window is being shown + */ void UserInterface::doControls() { - // TODO + Events &events = *_vm->_events; + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + Screen &screen = *_vm->_screen; + Sound &sound = *_vm->_sound; + Talk &talk = *_vm->_talk; + UserInterface &ui = *_vm->_ui; + int found; + byte color; + bool updateConfig = false; + + Settings settings(_vm); + settings.drawInteface(false); + + do { + if (_menuCounter) + whileMenuCounter(); + + found = -1; + _key = -1; + + scene.doBgAnim(); + if (talk._talkToAbort) + return; + + events.setButtonState(); + Common::Point pt = events.mousePos(); + + if (events._pressed || events._released || events.kbHit()) { + clearInfo(); + _key = -1; + + if (events.kbHit()) { + Common::KeyState keyState = events.getKey(); + _key = toupper(keyState.keycode); + + if (_key == Common::KEYCODE_RETURN || _key == Common::KEYCODE_SPACE) { + events._pressed = false; + events._oldButtons = 0; + _keycode = Common::KEYCODE_INVALID; + events._released = true; + } + } + + // Handle highlighting button under mouse + found = settings.drawButtons(pt, _key); + } + + if ((found == 0 && events._released) || (_key == 'E' || _key == Common::KEYCODE_ESCAPE)) + // Exit + break; + + if ((found == 1 && events._released) || _key == 'M') { + // Toggle music + if (sound._music) { + sound.stopSound(); + sound._music = false; + } else { + sound._music = true; + sound.startSong(); + } + + updateConfig = true; + settings.drawInteface(true); + } + + if ((found == 2 && events._released) || _key == 'V') { + sound._voices = !sound._voices; + updateConfig = true; + settings.drawInteface(true); + } + + if ((found == 3 && events._released) || _key == 'S') { + // Toggle sound effects + sound._digitized = !sound._digitized; + updateConfig = true; + settings.drawInteface(true); + } + + if ((found == 4 && events._released) || _key == 'A') { + // Help button style + ui._helpStyle ^= 1; + updateConfig = true; + settings.drawInteface(true); + } + + if ((found == 5 && events._released) || _key == 'N') { + // New font style + screen.setFont((screen.fontNumber() + 1) & 3); + } + + if ((found == 6 && events._released) || _key == 'J') { + // Toggle joystick + _vm->_joystick = !_vm->_joystick; + updateConfig = true; + settings.drawInteface(true); + } + + if ((found == 7 && events._released) || _key == 'C') { + // Calibrate joystick - No implementation in ScummVM + } + + if ((found == 8 && events._released) || _key == 'F') { + // Toggle fade style + screen._fadeStyle = !screen._fadeStyle; + updateConfig = true; + settings.drawInteface(true); + } + + if ((found == 9 && events._released) || _key == 'W') { + // Window style + ui._windowStyle ^= 1; + updateConfig = true; + settings.drawInteface(true); + } + + if ((found == 10 && events._released) || _key == 'P') { + // Toggle portraits being shown + people._portraitsOn = !people._portraitsOn; + updateConfig = true; + settings.drawInteface(true); + } + + if ((found == 11 && events._released) || _key == 'K') { + // Toggle keypad acceleration speed + _vm->_keyPadSpeed ^= 1; + updateConfig = true; + settings.drawInteface(true); + } + } while (!_vm->shouldQuit()); + + banishWindow(); + + if (updateConfig) + _vm->saveConfig(); + + _keycode = Common::KEYCODE_INVALID; + _keyboardInput = false; + _windowBounds.top = CONTROLS_Y1; + _key = -1; } /** diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index c4a07abc76..eaa8a3654b 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -61,9 +61,22 @@ extern const char *const PRESS_KEY_TO_CONTINUE; class SherlockEngine; class Inventory; class Talk; +class UserInterface; + +class Settings { +private: + SherlockEngine *_vm; +public: + Settings(SherlockEngine *vm) : _vm() {} + + void drawInteface(bool flag); + + int drawButtons(const Common::Point &pt, int key); +}; class UserInterface { friend class Inventory; + friend class Settings; friend class Talk; private: SherlockEngine *_vm; -- cgit v1.2.3 From 3be28b495dbedc3a94b366edd6178cbf0941cc77 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 13 Apr 2015 20:10:35 -0500 Subject: SHERLOCK: Implemented checkUseAction --- engines/sherlock/user_interface.cpp | 105 +++++++++++++++++++++++++++++++++--- engines/sherlock/user_interface.h | 3 +- 2 files changed, 98 insertions(+), 10 deletions(-) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 651844fd66..dc87cf130c 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1115,12 +1115,10 @@ void UserInterface::doInvControl() { if (_selector >= 0) // Use/Give inv object with scene object - checkUseAction(scene._bgShapes[_find]._use[0], inv[_selector]._name, - _muse, _find, temp - 2); + checkUseAction(&scene._bgShapes[_find]._use[0], inv[_selector]._name, MUSE, _find, temp - 2); else // Now inv object has been highlighted - checkUseAction(scene._bgShapes[_find]._use[0], "*SELF", _muse, - _find, temp - 2); + checkUseAction(&scene._bgShapes[_find]._use[0], "*SELF", MUSE, _find, temp - 2); _selector = _oldSelector = -1; } @@ -1716,7 +1714,6 @@ void UserInterface::doControls() { Talk &talk = *_vm->_talk; UserInterface &ui = *_vm->_ui; int found; - byte color; bool updateConfig = false; Settings settings(_vm); @@ -2157,9 +2154,101 @@ void UserInterface::banishWindow(bool slideUp) { _menuMode = STD_MODE; } -void UserInterface::checkUseAction(UseType &use, const Common::String &invName, - const Common::String &msg, int objNum, int giveMode) { - // TODO +/** + * Checks to see whether a USE action is valid on the given object + */ +void UserInterface::checkUseAction(const UseType *use, const Common::String &invName, + const char *const messages[], int objNum, int giveMode) { + Events &events = *_vm->_events; + Inventory &inv = *_vm->_inventory; + Scene &scene = *_vm->_scene; + Screen &screen = *_vm->_screen; + Talk &talk = *_vm->_talk; + bool printed = messages == nullptr; + + if (objNum >= 1000) { + // Holmes was specified, so do nothing + _infoFlag = true; + clearInfo(); + _infoFlag = true; + + // Display error message + _menuCounter = 30; + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "You can't do that to yourself."); + return; + } + + // Scan for target item + int targetNum = -1; + if (giveMode) { + for (int idx = 0; idx < 4 && targetNum == -1; ++idx) { + if ((scumm_stricmp(use[idx]._target.c_str(), "*GIVE*") == 0 || scumm_stricmp(use[idx]._target.c_str(), "*GIVEP*") == 0) + && scumm_stricmp(use[idx]._names[0].c_str(), invName.c_str()) == 0) { + // Found a match + targetNum = idx; + if (scumm_stricmp(use[idx]._target.c_str(), "*GIVE*") == 0) + inv.deleteItemFromInventory(invName); + } + } + } else { + for (int idx = 0; idx < 4 && targetNum == -1; ++idx) { + if (scumm_stricmp(use[idx]._target.c_str(), invName.c_str()) == 0) + targetNum = idx; + } + } + + if (targetNum != -1) { + // Found a target, so do the action + const UseType &action = use[targetNum]; + int messageNum = action._cAnimNum; + + events.setCursor(WAIT); + + if (action._useFlag) + _vm->setFlags(action._useFlag); + + if (action._cAnimNum != 99) { + if (action._cAnimNum == 0) + scene.startCAnim(9, action._cAnimSpeed); + else + scene.startCAnim(action._cAnimNum - 1, action._cAnimSpeed); + } + + if (!talk._talkToAbort) { + Object &obj = scene._bgShapes[objNum]; + for (int idx = 0; idx < 4 && !talk._talkToAbort; ++idx) { + if (obj.checkNameForCodes(action._names[idx], messages)) { + if (!talk._talkToAbort) + printed = true; + } + } + + // Print "Done..." as an ending, unless flagged for leaving scene or otherwise flagged + if (scene._goToScene != 1 && !printed && !talk._talkToAbort) { + _infoFlag++; + clearInfo(); + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "Done..."); + _menuCounter = 25; + } + } + } else { + // Couldn't find target, so print error + _infoFlag = true; + clearInfo(); + + if (giveMode) { + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "No, thank you."); + } else if (messages == nullptr) { + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "You can't do that."); + } else { + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, messages[0]); + } + + _infoFlag = true; + _menuCounter = 30; + } + + events.setCursor(ARROW); } /** diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index eaa8a3654b..23aca4e536 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -101,7 +101,6 @@ private: Common::String _descStr; int _windowStyle; int _find; - Common::String _muse; int _oldUse; private: void depressButton(int num); @@ -128,7 +127,7 @@ private: void environment(); void doControls(); - void checkUseAction(UseType &use, const Common::String &invName, const Common::String &msg, + void checkUseAction(const UseType *use, const Common::String &invName, const char *const messages[], int objNum, int giveMode); void checkAction(ActionType &action, const char *const messages[], int objNum); public: -- cgit v1.2.3 From 38b6aa70a82fb05ee7e1581a239e054a9d304827 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 13 Apr 2015 22:55:07 -0500 Subject: SHERLOCK: Fixes for talk setup and portrait loading --- engines/sherlock/objects.cpp | 1 - engines/sherlock/people.cpp | 8 ++++++-- engines/sherlock/people.h | 3 +++ engines/sherlock/sound.cpp | 6 +++--- engines/sherlock/talk.cpp | 35 ++++++++++++++++++----------------- engines/sherlock/user_interface.cpp | 3 +-- 6 files changed, 31 insertions(+), 25 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index cab35f9634..4cf26a3ad7 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -962,7 +962,6 @@ int Object::pickUpObject(const char *const messages[]) { bool printed = false; bool takeFlag = true; int numObjects = 0; - int message; if (pickup == 99) { for (int idx = 0; idx < 4 && !talk._talkToAbort; ++idx) { diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index e6a4eeed0f..5dd50e7e94 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -196,7 +196,7 @@ People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) { _oldWalkSequence = -1; _allowWalkAbort = false; _portraitLoaded = false; - _portraitsOn = false; + _portraitsOn = true; _clearingThePortrait = false; _srcZone = _destZone = 0; _talkPics = nullptr; @@ -204,12 +204,15 @@ People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) { _speakerFlip = false; _holmesFlip = false; _homesQuotient = 0; + + _portrait._sequences = new byte[32]; } People::~People() { if (_walkLoaded) delete _data[PLAYER]._images; delete _talkPics; + delete[] _portrait._sequences; } void People::reset() { @@ -646,7 +649,8 @@ void People::setTalking(int speaker) { if (_portraitsOn) { delete _talkPics; - _talkPics = new ImageFile("portrait.lib"); + Common::String filename = Common::String::format("%s.vgs", PORTRAITS[speaker]); + _talkPics = new ImageFile(filename); // Load portrait sequences Common::SeekableReadStream *stream = res.load("sequence.txt"); diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index 601fe6006b..593b516ee6 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -51,6 +51,9 @@ enum { MAP_DOWN = 5, MAP_DOWNLEFT = 6, MAP_LEFT = 2, MAP_UPLEFT = 8 }; +extern const char *const NAMES[MAX_PEOPLE]; +extern const char PORTRAITS[MAX_PEOPLE][5]; + class SherlockEngine; class Person: public Sprite { diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index 771d5db9d5..c3e50a8be2 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -25,9 +25,9 @@ namespace Sherlock { Sound::Sound(SherlockEngine *vm): _vm(vm) { - _soundOn = true; - _musicOn = true; - _speechOn = true; + _soundOn = false; + _musicOn = false; + _speechOn = false; _voices = 0; _playingEpilogue = false; _music = false; diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index a40d3ace2d..279e6de69a 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -96,9 +96,9 @@ void Statement::synchronize(Common::SeekableReadStream &s) { // Read in flag required/modified data for (uint idx = 0; idx < _required.size(); ++idx) - _required[idx] = s.readUint16LE(); + _required[idx] = s.readSint16LE(); for (uint idx = 0; idx < _modified.size(); ++idx) - _modified[idx] = s.readUint16LE(); + _modified[idx] = s.readSint16LE(); _portraitSide = s.readByte(); _quotient = s.readUint16LE(); @@ -583,8 +583,8 @@ void Talk::loadTalkFile(const Common::String &filename) { // Check for an existing person being talked to _talkTo = -1; - for (int idx = 0; idx < NUM_OF_PEOPLE; ++idx) { - if (!scumm_strnicmp(filename.c_str(), people[(PeopleId)idx]._portrait.c_str(), 4)) { + for (int idx = 0; idx < MAX_PEOPLE; ++idx) { + if (!scumm_strnicmp(filename.c_str(), PORTRAITS[idx], 4)) { _talkTo = idx; break; } @@ -1036,7 +1036,7 @@ void Talk::doScript(const Common::String &script) { ui.clearWindow(); // Need to switch speakers? - if (str[0] == SWITCH_SPEAKER) { + if ((byte)str[0] == SWITCH_SPEAKER) { _speaker = str[1] - 1; str += 2; pullSequence(); @@ -1048,7 +1048,7 @@ void Talk::doScript(const Common::String &script) { } // Assign portrait location? - if (str[0] == ASSIGN_PORTRAIT_LOCATION) { + if ((byte)str[0] == ASSIGN_PORTRAIT_LOCATION) { switch (str[1] & 15) { case 1: people._portraitSide = 20; @@ -1083,15 +1083,16 @@ void Talk::doScript(const Common::String &script) { Common::String tempString; wait = 0; - if (!str[0]) { + byte c = (byte)str[0]; + if (!c) { endStr = true; - } else if (str[0] == '{') { + } else if (c == '{') { // Start of comment, so skip over it while (*str++ != '}') ; - } else if (str[0] >= 128) { + } else if (c >= 128) { // Handle control code - switch (str[0]) { + switch (c) { case SWITCH_SPEAKER: // Save the current point in the script, since it might be intterupted by // doing bg anims in the next call, so we need to know where to return to @@ -1157,7 +1158,7 @@ void Talk::doScript(const Common::String &script) { // doing bg anims in the next call, so we need to know where to return to _scriptCurrentIndex = str - script.c_str(); - if (_speaker < 128) + if (_speaker >= 0 && _speaker < 128) people.clearTalking(); pullSequence(); if (_talkToAbort) @@ -1508,9 +1509,9 @@ void Talk::doScript(const Common::String &script) { // If the window is open, display the name directly on-screen. // Otherwise, simply draw it on the back buffer if (ui._windowOpen) { - screen.print(Common::Point(16, yp), TALK_FOREGROUND, inv._names[_speaker & 127].c_str()); + screen.print(Common::Point(16, yp), TALK_FOREGROUND, NAMES[_speaker & 127]); } else { - screen.gPrint(Common::Point(16, yp - 1), TALK_FOREGROUND, inv._names[_speaker & 127].c_str()); + screen.gPrint(Common::Point(16, yp - 1), TALK_FOREGROUND, NAMES[_speaker & 127]); openTalkWindow = true; } @@ -1523,10 +1524,10 @@ void Talk::doScript(const Common::String &script) { width += screen.charWidth(str[idx]); ++idx; ++charCount; - } while (width < 298 && str[idx] && str[idx] != '{' && str[idx] < 128); + } while (width < 298 && str[idx] && str[idx] != '{' && (byte)str[idx] < 128); if (str[idx] || width >= 298) { - if (str[idx] < 128 && str[idx] != '{') { + if ((byte)str[idx] < 128 && str[idx] != '{') { --idx; --charCount; } @@ -1565,7 +1566,7 @@ void Talk::doScript(const Common::String &script) { str += idx; // If line wrap occurred, then move to after the separating space between the words - if (str[0] < 128 && str[0] != '{') + if ((byte)str[0] < 128 && str[0] != '{') ++str; yp += 9; @@ -1578,7 +1579,7 @@ void Talk::doScript(const Common::String &script) { wait = 1; } - switch (str[0]) { + switch ((byte)str[0]) { case SWITCH_SPEAKER: case ASSIGN_PORTRAIT_LOCATION: case BANISH_WINDOW: diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index dc87cf130c..43ae76f94b 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -2200,7 +2200,6 @@ void UserInterface::checkUseAction(const UseType *use, const Common::String &inv if (targetNum != -1) { // Found a target, so do the action const UseType &action = use[targetNum]; - int messageNum = action._cAnimNum; events.setCursor(WAIT); @@ -2318,7 +2317,7 @@ void UserInterface::checkAction(ActionType &action, const char *const messages[] people[AL]._sequenceNumber = dir; people.gotoStand(people[AL]); - talk.talkTo(action._names[nameIdx] + 2); + talk.talkTo(action._names[nameIdx].c_str() + 2); if (ch == 'T') doCAnim = false; } -- cgit v1.2.3 From 97d3df3c9e7faa4b9925765c4612d341848cf08c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 13 Apr 2015 23:37:39 -0500 Subject: SHERLOCK: Fix for animating chracter portraits when talking --- engines/sherlock/scene.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 1cad2506e5..8a6681b5e0 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -1171,6 +1171,9 @@ void Scene::doBgAnim() { o.adjustObject(); } + if (people._portraitLoaded && people._portrait._type == ACTIVE_BG_SHAPE) + people._portrait.adjustObject(); + for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if (_canimShapes[idx]._type != INVALID) _canimShapes[idx].adjustObject(); -- cgit v1.2.3 From c58325b519371064348b747c957a89d009ac12ba Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 14 Apr 2015 19:53:03 -0500 Subject: SHERLOCK: Fix scene transition --- engines/sherlock/objects.cpp | 28 ++++++++++++++-------------- engines/sherlock/scene.cpp | 10 +++++++--- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 4cf26a3ad7..ca1bdfb2c5 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -693,24 +693,24 @@ bool Object::checkEndOfSequence() { setObjSequence(seq, false); } } - } - if (_allow && _frameNumber == 0) { - // canimation just ended - if (_type != NO_SHAPE && _type != REMOVE) { - _type = REMOVE; + if (_allow && _frameNumber == 0) { + // canimation just ended + if (_type != NO_SHAPE && _type != REMOVE) { + _type = REMOVE; - if (!_countCAnimFrames) { - // Save details before shape is removed - _delta.x = _imageFrame->_frame.w; - _delta.y = _imageFrame->_frame.h; - _position = _imageFrame->_offset; + if (!_countCAnimFrames) { + // Save details before shape is removed + _delta.x = _imageFrame->_frame.w; + _delta.y = _imageFrame->_frame.h; + _position = _imageFrame->_offset; - // Free the images - delete _images; + // Free the images + delete _images; + } + } else { + _type = INVALID; } - } else { - _type = INVALID; } } diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 8a6681b5e0..1ce2183af1 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -663,13 +663,13 @@ void Scene::transitionToScene() { if (cAnimNum != -1) { CAnim &c = _cAnim[cAnimNum]; - Common::Point pt = c._position; + Common::Point pt = c._goto; - c._position = Common::Point(-1, -1); + c._goto = Common::Point(-1, -1); people[AL]._position = Common::Point(0, 0); startCAnim(cAnimNum, 1); - c._position = pt; + c._goto = pt; } } @@ -875,7 +875,9 @@ int Scene::startCAnim(int cAnimNum, int playRate) { tpDir = cAnim._teleportDir; } + CursorId oldCursor = events.getCursor(); events.setCursor(WAIT); + _canimShapes.push_back(Object()); Object &cObj = _canimShapes[_canimShapes.size() - 1]; @@ -1040,6 +1042,8 @@ int Scene::startCAnim(int cAnimNum, int playRate) { people.gotoStand(people[AL]); } + events.setCursor(oldCursor); + return 1; } -- cgit v1.2.3 From f4af9fdbfd4531fd59c9f51785d573f6a128639e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 14 Apr 2015 20:14:09 -0500 Subject: SHERLOCK: Fix word-wrap of talk options --- engines/sherlock/talk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 279e6de69a..49e0677b80 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -795,7 +795,7 @@ int Talk::talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt // Handle potentially multiple lines needed to display entire statement const char *lineStartP = msg.c_str(); - int maxWidth = 298 - numberFlag ? 18 : 0; + int maxWidth = 298 - (numberFlag ? 18 : 0); for (;;) { // Get as much of the statement as possible will fit on the Common::String sLine; -- cgit v1.2.3 From b14debc20769c7c6e8b0d5fb1d189e319e5ad6e4 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 14 Apr 2015 20:30:02 -0500 Subject: SHERLOCK: Fix talking to Watson when he's sitting down --- engines/sherlock/talk.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 49e0677b80..73bf9b5fb3 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -591,8 +591,8 @@ void Talk::loadTalkFile(const Common::String &filename) { } const char *chP = strchr(filename.c_str(), '.'); - Common::String talkFile = !chP ? filename + ".tlk" : - Common::String(filename.c_str(), chP) + ".tlk"; + Common::String talkFile = chP ? Common::String(filename.c_str(), chP) + ".tlk" : + Common::String(filename.c_str(), filename.c_str() + 7) + ".tlk"; // Open the talk file for reading Common::SeekableReadStream *talkStream = res.load(talkFile); -- cgit v1.2.3 From 460a84e68f4a633b52a8654f93cdd81a2f3521e4 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 14 Apr 2015 21:24:24 -0500 Subject: SHERLOCK: Fix stopping Watson from moving when talking to him --- engines/sherlock/people.cpp | 2 +- engines/sherlock/talk.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 5dd50e7e94..cc26339bde 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -597,7 +597,7 @@ int People::findSpeaker(int speaker) { if (scumm_stricmp(PORTRAITS[speaker], name.c_str()) == 0 && obj._name[4] >= '0' && obj._name[4] <= '9') - return idx - 1; + return idx; } } diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 73bf9b5fb3..ef64edd66b 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -880,7 +880,7 @@ void Talk::clearSequences() { void Talk::pullSequence() { Scene &scene = *_vm->_scene; - if (_scriptStack.empty()) + if (_sequenceStack.empty()) return; SequenceEntry seq = _sequenceStack.pop(); -- cgit v1.2.3 From 5b97d581f655eed747a33a69ff7cb5bfe79763fd Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 14 Apr 2015 22:41:18 -0500 Subject: SHERLOCK: Fix horizontal flipping of Holmes when walking left --- engines/sherlock/scene.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 1ce2183af1..46ddbc425f 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -1229,9 +1229,9 @@ void Scene::doBgAnim() { int xRight = SHERLOCK_SCREEN_WIDTH - 2 - people[AL]._imageFrame->_frame.w; int tempX = MIN(people[AL]._position.x / 100, xRight); - bool flipped = people[AL]._frameNumber == WALK_LEFT || people[AL]._frameNumber == STOP_LEFT || - people[AL]._frameNumber == WALK_UPLEFT || people[AL]._frameNumber == STOP_UPLEFT || - people[AL]._frameNumber == WALK_DOWNRIGHT || people[AL]._frameNumber == STOP_DOWNRIGHT; + bool flipped = people[AL]._sequenceNumber == WALK_LEFT || people[AL]._sequenceNumber == STOP_LEFT || + people[AL]._sequenceNumber == WALK_UPLEFT || people[AL]._sequenceNumber == STOP_UPLEFT || + people[AL]._sequenceNumber == WALK_DOWNRIGHT || people[AL]._sequenceNumber == STOP_DOWNRIGHT; screen._backBuffer1.transBlitFrom(people[AL]._imageFrame->_frame, Common::Point(tempX, people[AL]._position.y / 100 - people[AL]._imageFrame->_frame.h), flipped); } -- cgit v1.2.3 From a830d7732537a913aa29ae4a4bc10e80e79dbc82 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 15 Apr 2015 07:49:10 -0500 Subject: SHERLOCK: Refactored out Scripts class --- engines/sherlock/module.mk | 1 - engines/sherlock/scripts.cpp | 42 --------------------------------- engines/sherlock/scripts.h | 54 ------------------------------------------- engines/sherlock/sherlock.cpp | 3 --- engines/sherlock/sherlock.h | 2 -- engines/sherlock/talk.cpp | 14 +++++++---- engines/sherlock/talk.h | 2 ++ 7 files changed, 12 insertions(+), 106 deletions(-) delete mode 100644 engines/sherlock/scripts.cpp delete mode 100644 engines/sherlock/scripts.h diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk index a01f9f0f71..4101769a80 100644 --- a/engines/sherlock/module.mk +++ b/engines/sherlock/module.mk @@ -18,7 +18,6 @@ MODULE_OBJS = \ resources.o \ scene.o \ screen.o \ - scripts.o \ sherlock.o \ sound.o \ talk.o \ diff --git a/engines/sherlock/scripts.cpp b/engines/sherlock/scripts.cpp deleted file mode 100644 index 02dcfa6f0b..0000000000 --- a/engines/sherlock/scripts.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "sherlock/scripts.h" -#include "sherlock/sherlock.h" - -namespace Sherlock { - -Scripts::Scripts(SherlockEngine *vm): _vm(vm) { - -} - -void Scripts::popStack() { - /* - ScriptEntry script = _scriptStack.pop(); - _scriptName = script._name; -// _scriptSaveIndex = script._index; - _scriptSelect = script._select; - */ -} - - -} // End of namespace Sherlock diff --git a/engines/sherlock/scripts.h b/engines/sherlock/scripts.h deleted file mode 100644 index beea726c8d..0000000000 --- a/engines/sherlock/scripts.h +++ /dev/null @@ -1,54 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef SHERLOCK_SCRIPTS_H -#define SHERLOCK_SCRIPTS_H - -#include "common/scummsys.h" -#include "common/stack.h" - -namespace Sherlock { - -class SherlockEngine; - -struct ScriptEntry { - Common::String _name; - int _index; - int _select; -}; - -class Scripts { -private: - SherlockEngine *_vm; -public: - -public: - Scripts(SherlockEngine *vm); - - void doScript(const Common::String &str); - - void popStack(); -}; - -} // End of namespace Sherlock - -#endif diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 72c072b640..c65a70a20f 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -39,7 +39,6 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _res = nullptr; _scene = nullptr; _screen = nullptr; - _scripts = nullptr; _sound = nullptr; _talk = nullptr; _ui = nullptr; @@ -59,7 +58,6 @@ SherlockEngine::~SherlockEngine() { delete _people; delete _scene; delete _screen; - delete _scripts; delete _sound; delete _talk; delete _ui; @@ -84,7 +82,6 @@ void SherlockEngine::initialize() { _people = new People(this); _scene = new Scene(this); _screen = new Screen(this); - _scripts = new Scripts(this); _sound = new Sound(this); _talk = new Talk(this); _ui = new UserInterface(this); diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index ef10cd2d47..ec8e0c3148 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -40,7 +40,6 @@ #include "sherlock/resources.h" #include "sherlock/scene.h" #include "sherlock/screen.h" -#include "sherlock/scripts.h" #include "sherlock/sound.h" #include "sherlock/talk.h" #include "sherlock/user_interface.h" @@ -90,7 +89,6 @@ public: Resources *_res; Scene *_scene; Screen *_screen; - Scripts *_scripts; Sound *_sound; Talk *_talk; UserInterface *_ui; diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index ef64edd66b..ee1e6201d2 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -160,7 +160,6 @@ void Talk::talkTo(const Common::String &filename) { People &people = *_vm->_people; Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; - Scripts &scripts = *_vm->_scripts; UserInterface &ui = *_vm->_ui; Common::Rect savedBounds = screen.getDisplayBounds(); bool abortFlag = false; @@ -459,9 +458,7 @@ void Talk::talkTo(const Common::String &filename) { // If a script was added to the script stack, restore state so that the // previous script can continue - if (!_scriptStack.empty()) { - scripts.popStack(); - } + popStack(); events.setCursor(ARROW); } @@ -1738,5 +1735,14 @@ int Talk::waitForMore(int delay) { return key2; } +void Talk::popStack() { + if (!_scriptStack.empty()) { + ScriptStackEntry scriptEntry = _scriptStack.pop(); + _scriptName = scriptEntry._name; + _scriptSaveIndex = scriptEntry._currentIndex; + _scriptSelect = scriptEntry._select; + _scriptMoreFlag = true; + } +} } // End of namespace Sherlock diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index bf4f12675c..4a33f2f557 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -143,6 +143,8 @@ public: void pushSequence(int speaker); void setSequence(int speaker); bool isSequencesEmpty() const { return _scriptStack.empty(); } + + void popStack(); }; } // End of namespace Sherlock -- cgit v1.2.3 From 17bf9e7f547d1893fbafb77dcc6703b21eca52c6 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 15 Apr 2015 08:22:40 -0500 Subject: SHERLOCK: Refactored Chess class to be Map class --- engines/sherlock/map.cpp | 46 +++++++++++++++++++++++++++++++ engines/sherlock/map.h | 52 ++++++++++++++++++++++++++++++++++++ engines/sherlock/module.mk | 2 +- engines/sherlock/objects.cpp | 7 ++--- engines/sherlock/people.cpp | 5 ++-- engines/sherlock/scalpel/chess.cpp | 37 ------------------------- engines/sherlock/scalpel/chess.h | 45 ------------------------------- engines/sherlock/scalpel/scalpel.cpp | 14 ++++------ engines/sherlock/scalpel/scalpel.h | 4 +-- engines/sherlock/scene.cpp | 10 ++++--- engines/sherlock/sherlock.cpp | 3 +++ engines/sherlock/sherlock.h | 3 ++- engines/sherlock/talk.cpp | 6 ++--- 13 files changed, 126 insertions(+), 108 deletions(-) create mode 100644 engines/sherlock/map.cpp create mode 100644 engines/sherlock/map.h delete mode 100644 engines/sherlock/scalpel/chess.cpp delete mode 100644 engines/sherlock/scalpel/chess.h diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp new file mode 100644 index 0000000000..8257c16a38 --- /dev/null +++ b/engines/sherlock/map.cpp @@ -0,0 +1,46 @@ +/* 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 "sherlock/map.h" + +namespace Sherlock { + +Map::Map(SherlockEngine *vm): _vm(vm) { +} + +/** + * Loads the list of points for locations on the map for each scene + */ +void Map::loadPoints(int count, const int *xList, const int *yList) { + for (int idx = 0; idx < count; ++idx, ++xList, ++yList) { + _points.push_back(Common::Point(*xList, *yList)); + } +} + +/** + * Show the map + */ +int Map::show() { + return 0; +} + +} // End of namespace Sherlock diff --git a/engines/sherlock/map.h b/engines/sherlock/map.h new file mode 100644 index 0000000000..88f2b75805 --- /dev/null +++ b/engines/sherlock/map.h @@ -0,0 +1,52 @@ +/* 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 SHERLOCK_MAP_H +#define SHERLOCK_MAP_H + +#include "common/scummsys.h" +#include "common/array.h" +#include "common/rect.h" +#include "common/str.h" + +namespace Sherlock { + +class SherlockEngine; + +class Map { +private: + SherlockEngine *_vm; + Common::Array _points; // Map locations for each scene +public: +public: + Map(SherlockEngine *vm); + + const Common::Point &operator[](int idx) { return _points[idx]; } + + void loadPoints(int count, const int *xList, const int *yList); + + int show(); +}; + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk index 4101769a80..171f704a1e 100644 --- a/engines/sherlock/module.mk +++ b/engines/sherlock/module.mk @@ -1,7 +1,6 @@ MODULE := engines/sherlock MODULE_OBJS = \ - scalpel/chess.o \ scalpel/darts.o \ scalpel/scalpel.o \ tattoo/tattoo.o \ @@ -13,6 +12,7 @@ MODULE_OBJS = \ graphics.o \ inventory.o \ journal.o \ + map.o \ objects.o \ people.o \ resources.o \ diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index ca1bdfb2c5..82daa90a38 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -801,6 +801,7 @@ void Object::setObjSequence(int seq, bool wait) { * @returns 0 if no codes are found, 1 if codes were found */ int Object::checkNameForCodes(const Common::String &name, const char *const messages[]) { + Map &map = *_vm->_map; People &people = *_vm->_people; Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; @@ -847,9 +848,9 @@ int Object::checkNameForCodes(const Common::String &name, const char *const mess if (ch >= '0' && ch <= '9') { scene._goToScene = atoi(name.c_str() + 1); - if (scene._goToScene < 97 && _vm->_map[scene._goToScene].x) { - _vm->_over.x = _vm->_map[scene._goToScene].x * 100 - 600; - _vm->_over.y = _vm->_map[scene._goToScene].y * 100 + 900; + if (scene._goToScene < 97 && map[scene._goToScene].x) { + _vm->_over.x = map[scene._goToScene].x * 100 - 600; + _vm->_over.y = map[scene._goToScene].y * 100 + 900; } if ((p = strchr(name.c_str(), ',')) != nullptr) { diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index cc26339bde..d22c08f625 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -415,6 +415,7 @@ void People::setWalking() { * is being displayed, then the chraracter will always face down. */ void People::gotoStand(Sprite &sprite) { + Map &map = *_vm->_map; Scene &scene = *_vm->_scene; _walkTo.clear(); sprite._walkCount = 0; @@ -448,8 +449,8 @@ void People::gotoStand(Sprite &sprite) { if (_vm->_onChessboard) { sprite._sequenceNumber = 0; - _data[AL]._position.x = (_vm->_map[scene._charPoint].x - 6) * 100; - _data[AL]._position.y = (_vm->_map[scene._charPoint].x + 10) * 100; + _data[AL]._position.x = (map[scene._charPoint].x - 6) * 100; + _data[AL]._position.y = (map[scene._charPoint].x + 10) * 100; } _oldWalkSequence = -1; diff --git a/engines/sherlock/scalpel/chess.cpp b/engines/sherlock/scalpel/chess.cpp deleted file mode 100644 index 95c662dd01..0000000000 --- a/engines/sherlock/scalpel/chess.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "sherlock/scalpel/chess.h" -#include "sherlock/scalpel/scalpel.h" - -namespace Sherlock { - -namespace Scalpel { - -int Chess::doChessBoard() { - // TODO - return 0; -} - -} // End of namespace Scalpel - -} // End of namespace Scalpel diff --git a/engines/sherlock/scalpel/chess.h b/engines/sherlock/scalpel/chess.h deleted file mode 100644 index 70607472c2..0000000000 --- a/engines/sherlock/scalpel/chess.h +++ /dev/null @@ -1,45 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef SHERLOCK_CHESS_H -#define SHERLOCK_CHESS_H - -namespace Sherlock { - -namespace Scalpel { - -class ScalpelEngine; - -class Chess { -private: - ScalpelEngine *_vm; -public: - Chess(ScalpelEngine *vm) : _vm(vm) {} - - int doChessBoard(); -}; - -} // End of namespace Scalpel - -} // End of namespace Sherlock - -#endif diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 954ea12aec..0742d05366 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -183,13 +183,11 @@ byte TALK_SEQUENCES[MAX_PEOPLE][MAX_TALK_SEQUENCES] = { ScalpelEngine::ScalpelEngine(OSystem *syst, const SherlockGameDescription *gameDesc) : SherlockEngine(syst, gameDesc) { - _chess = nullptr; _darts = nullptr; - _chessResult = 0; + _mapResult = 0; } ScalpelEngine::~ScalpelEngine() { - delete _chess; delete _darts; } @@ -199,7 +197,6 @@ ScalpelEngine::~ScalpelEngine() { void ScalpelEngine::initialize() { SherlockEngine::initialize(); - _chess = new Chess(this); _darts = new Darts(this); _flags.resize(100 * 8); @@ -207,8 +204,7 @@ void ScalpelEngine::initialize() { _flags[39] = true; // Turn on Baker Street // Load the map co-ordinates for each scene - for (int idx = 0; idx < NUM_PLACES; ++idx) - _map.push_back(Common::Point(MAP_X[idx], MAP_Y[idx])); + _map->loadPoints(NUM_PLACES, &MAP_X[0], &MAP_Y[0]); // Load the inventory loadInventory(); @@ -393,7 +389,7 @@ void ScalpelEngine::startScene() { } } - _scene->_goToScene = _chess->doChessBoard(); + _scene->_goToScene = _map->show(); _sound->freeSong(); _scene->_hsavedPos = Common::Point(-1, -1); @@ -533,10 +529,10 @@ void ScalpelEngine::startScene() { if (_scene->_goToScene == 99) { // Chess Board _darts->playDarts(); - _chessResult = _scene->_goToScene = 19; // Go back to the bar + _mapResult = _scene->_goToScene = 19; // Go back to the bar } - _chessResult = _scene->_goToScene; + _mapResult = _scene->_goToScene; } /** diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h index 34d017e757..aa00acab84 100644 --- a/engines/sherlock/scalpel/scalpel.h +++ b/engines/sherlock/scalpel/scalpel.h @@ -24,7 +24,6 @@ #define SHERLOCK_SCALPEL_H #include "sherlock/sherlock.h" -#include "sherlock/scalpel/chess.h" #include "sherlock/scalpel/darts.h" namespace Sherlock { @@ -33,9 +32,8 @@ namespace Scalpel { class ScalpelEngine : public SherlockEngine { private: - Chess *_chess; Darts *_darts; - int _chessResult; + int _mapResult; bool showCityCutscene(); bool showAlleyCutscene(); diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 46ddbc425f..575523bc45 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -193,6 +193,7 @@ void Scene::freeScene() { */ bool Scene::loadScene(const Common::String &filename) { Events &events = *_vm->_events; + Map &map = *_vm->_map; People &people = *_vm->_people; Screen &screen = *_vm->_screen; Sound &sound = *_vm->_sound; @@ -437,8 +438,8 @@ bool Scene::loadScene(const Common::String &filename) { // Reset the position on the overland map _vm->_oldCharPoint = _currentScene; - _vm->_over.x = _vm->_map[_currentScene].x * 100 - 600; - _vm->_over.y = _vm->_map[_currentScene].y * 100 + 900; + _vm->_over.x = map[_currentScene].x * 100 - 600; + _vm->_over.y = map[_currentScene].y * 100 + 900; events.clearEvents(); return flag; @@ -843,6 +844,7 @@ void Scene::checkBgShapes(ImageFrame *frame, const Common::Point &pt) { */ int Scene::startCAnim(int cAnimNum, int playRate) { Events &events = *_vm->_events; + Map &map = *_vm->_map; People &people = *_vm->_people; Resources &res = *_vm->_res; Talk &talk = *_vm->_talk; @@ -1027,8 +1029,8 @@ int Scene::startCAnim(int cAnimNum, int playRate) { if (gotoCode > 0 && !talk._talkToAbort) { _goToScene = gotoCode; - if (_goToScene < 97 && _vm->_map[_goToScene].x) { - _overPos = _vm->_map[_goToScene]; + if (_goToScene < 97 && map[_goToScene].x) { + _overPos = map[_goToScene]; } } diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index c65a70a20f..632e388642 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -35,6 +35,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _events = nullptr; _inventory = nullptr; _journal = nullptr; + _map = nullptr; _people = nullptr; _res = nullptr; _scene = nullptr; @@ -55,6 +56,7 @@ SherlockEngine::~SherlockEngine() { delete _debugger; delete _events; delete _journal; + delete _map; delete _people; delete _scene; delete _screen; @@ -78,6 +80,7 @@ void SherlockEngine::initialize() { _debugger = new Debugger(this); _events = new Events(this); _inventory = new Inventory(this); + _map = new Map(this); _journal = new Journal(this); _people = new People(this); _scene = new Scene(this); diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index ec8e0c3148..42e2cf8b38 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -36,6 +36,7 @@ #include "sherlock/events.h" #include "sherlock/inventory.h" #include "sherlock/journal.h" +#include "sherlock/map.h" #include "sherlock/people.h" #include "sherlock/resources.h" #include "sherlock/scene.h" @@ -85,6 +86,7 @@ public: Events *_events; Inventory *_inventory; Journal *_journal; + Map *_map; People *_people; Resources *_res; Scene *_scene; @@ -101,7 +103,6 @@ public: bool _loadingSavedGame; int _oldCharPoint; // Old scene Common::Point _over; // Old map position - Common::Array _map; // Map locations for each scene bool _onChessboard; bool _slowChess; bool _joystick; diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index ee1e6201d2..158cae38a9 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -574,7 +574,6 @@ void Talk::freeTalkVars() { * conversation. If found, the data for that conversation is loaded */ void Talk::loadTalkFile(const Common::String &filename) { - People &people = *_vm->_people; Resources &res = *_vm->_res; Sound &sound = *_vm->_sound; @@ -1000,6 +999,7 @@ void Talk::doScript(const Common::String &script) { Animation &anim = *_vm->_animation; Events &events = *_vm->_events; Inventory &inv = *_vm->_inventory; + Map &map = *_vm->_map; People &people = *_vm->_people; Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; @@ -1351,8 +1351,8 @@ void Talk::doScript(const Common::String &script) { if (scene._goToScene != 100) { // Not going to the map overview scene._oldCharPoint = scene._goToScene; - scene._overPos.x = _vm->_map[scene._goToScene].x * 100 - 600; - scene._overPos.y = _vm->_map[scene._goToScene].y * 100 + 900; + scene._overPos.x = map[scene._goToScene].x * 100 - 600; + scene._overPos.y = map[scene._goToScene].y * 100 + 900; // Run a canimation? if (str[2] > 100) { -- cgit v1.2.3 From 9ba234c0e09c4fc034ddd82f82483e10e2470dec Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 16 Apr 2015 17:32:11 -0500 Subject: SHERLOCK: Implemented Map::show method --- engines/sherlock/events.cpp | 10 +- engines/sherlock/events.h | 1 + engines/sherlock/map.cpp | 271 +++++++++++++++++++++++++++++++++++++++++++- engines/sherlock/map.h | 32 +++++- 4 files changed, 309 insertions(+), 5 deletions(-) diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index 67d09e52b2..79fe1b58d4 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -67,9 +67,15 @@ void Events::setCursor(CursorId cursorId) { // Set the cursor data Graphics::Surface &s = (*_cursorImages)[cursorId]; - CursorMan.replaceCursor(s.getPixels(), s.w, s.h, 0, 0, 0xff); - showCursor(); + setCursor(s); +} + +/** + * Set the cursor to show from a passed frame + */ +void Events::setCursor(const Graphics::Surface &src) { + CursorMan.replaceCursor(src.getPixels(), src.w, src.h, 0, 0, 0xff); } /** diff --git a/engines/sherlock/events.h b/engines/sherlock/events.h index 71f7623002..ccf6eb1c59 100644 --- a/engines/sherlock/events.h +++ b/engines/sherlock/events.h @@ -63,6 +63,7 @@ public: void loadCursors(const Common::String &filename); void setCursor(CursorId cursorId); + void setCursor(const Graphics::Surface &src); void showCursor(); diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index 8257c16a38..aae8d683c0 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -21,10 +21,20 @@ */ #include "sherlock/map.h" +#include "sherlock/sherlock.h" namespace Sherlock { -Map::Map(SherlockEngine *vm): _vm(vm) { +Map::Map(SherlockEngine *vm): _vm(vm), _topLine(SHERLOCK_SCREEN_WIDTH, 12) { + _shapes = nullptr; + _iconShapes = nullptr; + _point = 0; + _placesShown = false; + _charPoint = -1; + for (int idx = 0; idx < 3; ++idx) + Common::fill(&_sequences[idx][0], &_sequences[idx][MAX_FRAME], 0); + + loadData(); } /** @@ -36,11 +46,268 @@ void Map::loadPoints(int count, const int *xList, const int *yList) { } } +/** + * Load data needed for the map + */ +void Map::loadData() { + // Load the list of location names + Common::SeekableReadStream *txtStream = _vm->_res->load("chess.txt"); + char c; + + while (txtStream->pos() < txtStream->size()) { + Common::String line; + while ((c = txtStream->readByte()) != '\0') + line += c; + + _locationNames.push_back(line); + } + + delete txtStream; + + // Load the path data + Common::SeekableReadStream *pathStream = _vm->_res->load("chess.pth"); + + _paths.resize(31); + for (uint idx = 0; idx < _paths.size(); ++idx) { + _paths[idx].resize(_paths.size()); + + for (uint idx2 = 0; idx2 < _paths.size(); ++idx2) + _paths[idx][idx2] = pathStream->readSint16LE(); + } + + // Load in the path point information + _pathPoints.resize(416); + for (uint idx = 0; idx < _pathPoints.size(); ++idx) + _pathPoints[idx] = pathStream->readSint16LE(); + + delete pathStream; +} + /** * Show the map */ int Map::show() { - return 0; + Events &events = *_vm->_events; + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + Screen &screen = *_vm->_screen; + Common::Point lDrawn(-1, -1); + bool changed = false, exitFlag = false; + bool drawMap = true; + + // Set font and custom cursor for the map + int oldFont = screen.fontNumber(); + screen.setFont(0); + + ImageFile mapCursors("omouse.vgs"); + events.setCursor(mapCursors[0]); + + // Load the entire map + ImageFile bigMap("bigmap.vgs"); + + // Load need sprites + setupSprites(); + + screen._backBuffer1.blitFrom(bigMap[1], Common::Point(-_bigPos.x, -_bigPos.y)); + screen._backBuffer1.blitFrom(bigMap[2], Common::Point(-_bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y)); + screen._backBuffer1.blitFrom(bigMap[3], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, -_bigPos.y)); + screen._backBuffer1.blitFrom(bigMap[4], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y)); + + _point = -1; + people[AL]._position = _lDrawnPos = _overPos; + + // Show place icons + showPlaces(); + saveTopLine(); + _placesShown = true; + + // Keep looping until either a location is picked, or the game is ended + while (!_vm->shouldQuit() && !exitFlag) { + events.pollEventsAndWait(); + events.setButtonState(); + + // Keyboard handling + if (events.kbHit()) { + Common::KeyState keyState = events.getKey(); + + if (keyState.keycode == Common::KEYCODE_RETURN || keyState.keycode == Common::KEYCODE_SPACE) { + // Both space and enter simulate a mouse release + events._pressed = false; + events._released = true; + events._oldButtons = 0; + } + } + + // Ignore scrolling attempts until the screen is drawn + if (!drawMap) { + Common::Point pt = events.mousePos(); + + // Check for vertical map scrolling + if ((pt.y > (SHERLOCK_SCREEN_HEIGHT - 10) && _bigPos.y < 200) || (pt.y < 10 && _bigPos.y > 0)) { + if (pt.y > (SHERLOCK_SCREEN_HEIGHT - 10)) + _bigPos.y += 10; + else + _bigPos.y -= 10; + + changed = true; + } + + // Check for horizontal map scrolling + if ((pt.x > (SHERLOCK_SCREEN_WIDTH - 10) && _bigPos.x < 315) || (pt.x < 10 && _bigPos.x > 0)) { + if (pt.x > (SHERLOCK_SCREEN_WIDTH - 10)) + _bigPos.x += 15; + else + _bigPos.x -= 15; + + changed = true; + } + } + + if (changed) { + // Map has scrolled, so redraw new map view + changed = false; + + screen._backBuffer1.blitFrom(bigMap[1], Common::Point(-_bigPos.x, -_bigPos.y)); + screen._backBuffer1.blitFrom(bigMap[2], Common::Point(-_bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y)); + screen._backBuffer1.blitFrom(bigMap[3], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, -_bigPos.y)); + screen._backBuffer1.blitFrom(bigMap[4], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y)); + + showPlaces(); + _placesShown = false; + + saveTopLine(); + _savedPos.x = -1; + updateMap(true); + } else if (!drawMap) { + if (!_placesShown) { + showPlaces(); + _placesShown = true; + } + + updateMap(false); + } + + if ((events._released || events._rightReleased) && _point != -1) { + if (people[AL]._walkCount == 0) { + _charPoint = _point; + walkTheStreets(); + + events.setCursor(mapCursors[1]); + } + } + + // Check if a scene has beeen selected and we've finished "moving" to it + if (people[AL]._walkCount == 0) { + if (_charPoint >= 1 && _charPoint < (int)_points.size()) + exitFlag = true; + } + + if (drawMap) { + drawMap = false; + + if (screen._fadeStyle) + screen.randomTransition(); + else + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + } + + // Wait for a frame + events.wait(1); + } + + freeSprites(); + _overPos = people[AL]._position; + + // Reset font and cursor + screen.setFont(oldFont); + events.setCursor(ARROW); + + return _charPoint; +} + +/** + * Load and initialize all the sprites that are needed for the map display + */ +void Map::setupSprites() { + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + typedef byte Sequences[16][MAX_FRAME]; + _savedPos.x = -1; + + _shapes = new ImageFile("mapicon.vgs"); + _iconShapes = new ImageFile("overicon.vgs"); + + Person &p = people[AL]; + p._description = " "; + p._type = CHARACTER; + p._position = Common::Point(12400, 5000); + p._sequenceNumber = 0; + p._sequences = (Sequences *)&_sequences; + p._images = _shapes; + p._imageFrame = nullptr; + p._frameNumber = 0; + p._delta = Common::Point(0, 0); + p._oldSize = Common::Point(0, 0); + p._oldSize = Common::Point(0, 0); + p._misc = 0; + p._walkCount = 0; + p._allow = 0; + p._noShapeSize = Common::Point(0, 0); + p._goto = Common::Point(28000, 15000); + p._status = 0; + p.setImageFrame(); + + scene._bgShapes.clear(); +} + +/** + * Free the sprites and data used by the map + */ +void Map::freeSprites() { + delete _shapes; + delete _iconShapes; +} + +/** + * Draws an icon for every place that's currently known + */ +void Map::showPlaces() { + Screen &screen = *_vm->_screen; + + for (uint idx = 0; idx < _points.size(); ++idx) { + const Common::Point &pt = _points[idx]; + + if (pt.x != 0 && pt.y != 0) { + if (pt.x >= _bigPos.x && (pt.x - _bigPos.x) < SHERLOCK_SCREEN_WIDTH + && pt.y >= _bigPos.y && (pt.y - _bigPos.y) < SHERLOCK_SCREEN_HEIGHT) { + if (_vm->readFlags(idx)) { + screen._backBuffer1.transBlitFrom((*_iconShapes)[idx], + Common::Point(pt.x - _bigPos.x - 6, pt.y - _bigPos.y - 12)); + } + } + } + } +} + +/** + * Makes a copy of the top rows of the screen that are used to display location names + */ +void Map::saveTopLine() { + _topLine.blitFrom(_vm->_screen->_backBuffer1, Common::Point(0, 0), Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, 12)); +} + +/** + * Update all on-screen sprites to account for any scrolling of the map + */ +void Map::updateMap(bool flushScreen) { + // TODO +} + +/** + * Handle moving icon for player from their previous location on the map to a destination location + */ +void Map::walkTheStreets() { + // TODO } } // End of namespace Sherlock diff --git a/engines/sherlock/map.h b/engines/sherlock/map.h index 88f2b75805..32051d60b7 100644 --- a/engines/sherlock/map.h +++ b/engines/sherlock/map.h @@ -27,6 +27,9 @@ #include "common/array.h" #include "common/rect.h" #include "common/str.h" +#include "common/str-array.h" +#include "sherlock/graphics.h" +#include "sherlock/objects.h" namespace Sherlock { @@ -36,7 +39,34 @@ class Map { private: SherlockEngine *_vm; Common::Array _points; // Map locations for each scene -public: + Common::StringArray _locationNames; + Common::Array< Common::Array > _paths; + Common::Array _pathPoints; + Common::Point _savedPos; + Common::Point _savedSize; + Surface _topLine; + ImageFile *_shapes; + ImageFile *_iconShapes; + byte _sequences[3][MAX_FRAME]; + Common::Point _bigPos; + Common::Point _overPos; + Common::Point _lDrawnPos; + int _point; + bool _placesShown; + int _charPoint; +private: + void loadData(); + + void setupSprites(); + void freeSprites(); + + void showPlaces(); + + void saveTopLine(); + + void updateMap(bool flushScreen); + + void walkTheStreets(); public: Map(SherlockEngine *vm); -- cgit v1.2.3 From 19142ef58a3e632b31a87a99b817e261f47c1bc4 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 17 Apr 2015 00:07:31 -0500 Subject: SHERLOCK: Implement map icon drawing/restoring --- engines/sherlock/graphics.cpp | 13 ++++- engines/sherlock/graphics.h | 2 + engines/sherlock/map.cpp | 116 ++++++++++++++++++++++++++++++++++++++---- engines/sherlock/map.h | 7 +++ 4 files changed, 126 insertions(+), 12 deletions(-) diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index 306ff23548..6e986c839b 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -28,7 +28,7 @@ namespace Sherlock { Surface::Surface(uint16 width, uint16 height): _freePixels(true) { - create(width, height, Graphics::PixelFormat::createFormatCLUT8()); + create(width, height); } Surface::Surface(Surface &src, const Common::Rect &r) : _freePixels(false) { @@ -39,12 +39,23 @@ Surface::Surface(Surface &src, const Common::Rect &r) : _freePixels(false) { format = Graphics::PixelFormat::createFormatCLUT8(); } +Surface::Surface() : _freePixels(false) { +} Surface::~Surface() { if (_freePixels) free(); } +void Surface::create(uint16 width, uint16 height) { + if (_freePixels) + free(); + + Graphics::Surface::create(width, height, Graphics::PixelFormat::createFormatCLUT8()); + _freePixels = true; +} + + /** * Copy a surface into this one */ diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index b54dc1ec37..85f3ba8c40 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -40,8 +40,10 @@ protected: Surface(Surface &src, const Common::Rect &r); public: Surface(uint16 width, uint16 height); + Surface(); ~Surface(); + void create(uint16 width, uint16 height); void blitFrom(const Graphics::Surface &src); void blitFrom(const Graphics::Surface &src, const Common::Point &pt); void blitFrom(const Graphics::Surface &src, const Common::Point &pt, diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index aae8d683c0..fa3bf99cab 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -26,11 +26,14 @@ namespace Sherlock { Map::Map(SherlockEngine *vm): _vm(vm), _topLine(SHERLOCK_SCREEN_WIDTH, 12) { + _mapCursors = nullptr; _shapes = nullptr; _iconShapes = nullptr; _point = 0; _placesShown = false; _charPoint = -1; + _cursorIndex = -1; + _drawMap = false; for (int idx = 0; idx < 3; ++idx) Common::fill(&_sequences[idx][0], &_sequences[idx][MAX_FRAME], 0); @@ -89,19 +92,14 @@ void Map::loadData() { int Map::show() { Events &events = *_vm->_events; People &people = *_vm->_people; - Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; Common::Point lDrawn(-1, -1); bool changed = false, exitFlag = false; - bool drawMap = true; // Set font and custom cursor for the map int oldFont = screen.fontNumber(); screen.setFont(0); - ImageFile mapCursors("omouse.vgs"); - events.setCursor(mapCursors[0]); - // Load the entire map ImageFile bigMap("bigmap.vgs"); @@ -113,6 +111,7 @@ int Map::show() { screen._backBuffer1.blitFrom(bigMap[3], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, -_bigPos.y)); screen._backBuffer1.blitFrom(bigMap[4], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y)); + _drawMap = true; _point = -1; people[AL]._position = _lDrawnPos = _overPos; @@ -139,7 +138,7 @@ int Map::show() { } // Ignore scrolling attempts until the screen is drawn - if (!drawMap) { + if (!_drawMap) { Common::Point pt = events.mousePos(); // Check for vertical map scrolling @@ -178,7 +177,7 @@ int Map::show() { saveTopLine(); _savedPos.x = -1; updateMap(true); - } else if (!drawMap) { + } else if (!_drawMap) { if (!_placesShown) { showPlaces(); _placesShown = true; @@ -192,7 +191,8 @@ int Map::show() { _charPoint = _point; walkTheStreets(); - events.setCursor(mapCursors[1]); + _cursorIndex = 1; + events.setCursor((*_mapCursors)[_cursorIndex]); } } @@ -202,8 +202,8 @@ int Map::show() { exitFlag = true; } - if (drawMap) { - drawMap = false; + if (_drawMap) { + _drawMap = false; if (screen._fadeStyle) screen.randomTransition(); @@ -229,11 +229,16 @@ int Map::show() { * Load and initialize all the sprites that are needed for the map display */ void Map::setupSprites() { + Events &events = *_vm->_events; People &people = *_vm->_people; Scene &scene = *_vm->_scene; typedef byte Sequences[16][MAX_FRAME]; _savedPos.x = -1; + _mapCursors = new ImageFile("omouse.vgs"); + _cursorIndex = 0; + events.setCursor((*_mapCursors)[_cursorIndex]); + _shapes = new ImageFile("mapicon.vgs"); _iconShapes = new ImageFile("overicon.vgs"); @@ -264,6 +269,7 @@ void Map::setupSprites() { * Free the sprites and data used by the map */ void Map::freeSprites() { + delete _mapCursors; delete _shapes; delete _iconShapes; } @@ -300,7 +306,49 @@ void Map::saveTopLine() { * Update all on-screen sprites to account for any scrolling of the map */ void Map::updateMap(bool flushScreen) { - // TODO + Events &events = *_vm->_events; + People &people = *_vm->_people; + Screen &screen = *_vm->_screen; + Common::Point osPos = _savedPos; + Common::Point osSize = _savedSize; + Common::Point hPos; + + if (_cursorIndex >= 1) { + if (++_cursorIndex > (1 + 8)) + _cursorIndex = 1; + + events.setCursor((*_mapCursors)[_cursorIndex]); + } + + if (!_drawMap && !flushScreen) + restoreIcon(); + else + _savedPos.x = -1; + + people[AL].adjustSprite(); + + _lDrawnPos.x = hPos.x = people[AL]._position.x / 100 - _bigPos.x; + _lDrawnPos.y = hPos.y = people[AL]._position.y / 100 - people[AL].frameHeight() - _bigPos.y; + + // Draw the person icon + saveIcon(people[AL]._imageFrame, hPos); + if (people[AL]._sequenceNumber == MAP_DOWNLEFT || people[AL]._sequenceNumber == MAP_LEFT + || people[AL]._sequenceNumber == MAP_UPLEFT) + screen._backBuffer1.transBlitFrom(people[AL]._imageFrame->_frame, hPos, true); + else + screen._backBuffer1.transBlitFrom(people[AL]._imageFrame->_frame, hPos, false); + + if (flushScreen) { + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + } else if (!_drawMap) { + if (hPos.x > 0 && hPos.y >= 0 && hPos.x < SHERLOCK_SCREEN_WIDTH && hPos.y < SHERLOCK_SCREEN_HEIGHT) + screen.flushImage(people[AL]._imageFrame, Common::Point(people[AL]._position.x / 100 - _bigPos.x, + people[AL]._position.y / 100 - people[AL].frameHeight() - _bigPos.y), + &people[AL]._oldPosition.x, &people[AL]._oldPosition.y, &people[AL]._oldSize.x, &people[AL]._oldSize.y); + + if (osPos.x != -1) + screen.slamArea(osPos.x, osPos.y, osSize.x, osSize.y); + } } /** @@ -310,4 +358,50 @@ void Map::walkTheStreets() { // TODO } +/** + * Save the area under the player's icon + */ +void Map::saveIcon(ImageFrame *src, const Common::Point &pt) { + Screen &screen = *_vm->_screen; + Common::Point size(src->_width, src->_height); + Common::Point pos = pt; + + if (pos.x < 0) { + size.x += pos.x; + pos.x = 0; + } + + if (pos.y < 0) { + size.y += pos.y; + pos.y = 0; + } + + if ((pos.x + size.x) > SHERLOCK_SCREEN_WIDTH) + size.x -= (pos.x + size.x) - SHERLOCK_SCREEN_WIDTH; + + if ((pos.y + size.y) > SHERLOCK_SCREEN_HEIGHT) + size.y -= (pos.y + size.y) - SHERLOCK_SCREEN_HEIGHT; + + if (size.x < 1 || size.y < 1 || pos.x >= SHERLOCK_SCREEN_WIDTH || pos.y >= SHERLOCK_SCREEN_HEIGHT || _drawMap) { + // Flag as the area not needing to be saved + _savedPos.x = -1; + return; + } + + _iconSave.create(size.x, size.y); + _iconSave.blitFrom(screen._backBuffer1, Common::Point(0, 0), + Common::Rect(pos.x, pos.y, pos.x + size.x, pos.y + size.y)); +} + +/** + * Restore the area under the player's icon + */ +void Map::restoreIcon() { + Screen &screen = *_vm->_screen; + + if (_savedPos.x >= 0 && _savedPos.y >= 0 && _savedPos.x <= SHERLOCK_SCREEN_WIDTH + && _savedPos.y < SHERLOCK_SCREEN_HEIGHT) + screen._backBuffer1.blitFrom(_iconSave, _savedPos); +} + } // End of namespace Sherlock diff --git a/engines/sherlock/map.h b/engines/sherlock/map.h index 32051d60b7..653d8c0084 100644 --- a/engines/sherlock/map.h +++ b/engines/sherlock/map.h @@ -45,6 +45,7 @@ private: Common::Point _savedPos; Common::Point _savedSize; Surface _topLine; + ImageFile *_mapCursors; ImageFile *_shapes; ImageFile *_iconShapes; byte _sequences[3][MAX_FRAME]; @@ -54,6 +55,9 @@ private: int _point; bool _placesShown; int _charPoint; + int _cursorIndex; + bool _drawMap; + Surface _iconSave; private: void loadData(); @@ -67,6 +71,9 @@ private: void updateMap(bool flushScreen); void walkTheStreets(); + + void saveIcon(ImageFrame *src, const Common::Point &pt); + void restoreIcon(); public: Map(SherlockEngine *vm); -- cgit v1.2.3 From bfb86a99db6358043a4c16371c5a927411b4e8cb Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 20 Apr 2015 01:07:54 -0500 Subject: SHERLOCK: Map path walking, beginnings of darts game --- engines/sherlock/map.cpp | 74 ++++++- engines/sherlock/map.h | 19 +- engines/sherlock/scalpel/darts.cpp | 385 +++++++++++++++++++++++++++++++++++ engines/sherlock/scalpel/darts.h | 33 ++- engines/sherlock/scalpel/scalpel.cpp | 8 +- 5 files changed, 504 insertions(+), 15 deletions(-) diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index fa3bf99cab..6fd169f43a 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -31,7 +31,7 @@ Map::Map(SherlockEngine *vm): _vm(vm), _topLine(SHERLOCK_SCREEN_WIDTH, 12) { _iconShapes = nullptr; _point = 0; _placesShown = false; - _charPoint = -1; + _charPoint = _oldCharPoint = -1; _cursorIndex = -1; _drawMap = false; for (int idx = 0; idx < 3; ++idx) @@ -43,9 +43,9 @@ Map::Map(SherlockEngine *vm): _vm(vm), _topLine(SHERLOCK_SCREEN_WIDTH, 12) { /** * Loads the list of points for locations on the map for each scene */ -void Map::loadPoints(int count, const int *xList, const int *yList) { - for (int idx = 0; idx < count; ++idx, ++xList, ++yList) { - _points.push_back(Common::Point(*xList, *yList)); +void Map::loadPoints(int count, const int *xList, const int *yList, const int *transList) { + for (int idx = 0; idx < count; ++idx, ++xList, ++yList, ++transList) { + _points.push_back(MapEntry(*xList, *yList, *transList)); } } @@ -79,9 +79,11 @@ void Map::loadData() { } // Load in the path point information - _pathPoints.resize(416); - for (uint idx = 0; idx < _pathPoints.size(); ++idx) - _pathPoints[idx] = pathStream->readSint16LE(); + _pathPoints.resize(208); + for (uint idx = 0; idx < _pathPoints.size(); ++idx) { + _pathPoints[idx].x = pathStream->readSint16LE(); + _pathPoints[idx].y = pathStream->readSint16LE(); + } delete pathStream; } @@ -302,6 +304,14 @@ void Map::saveTopLine() { _topLine.blitFrom(_vm->_screen->_backBuffer1, Common::Point(0, 0), Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, 12)); } +/** + * Erases anything shown in the top line by restoring the previously saved original map background + */ +void Map::eraseTopLine() { + Screen &screen = *_vm->_screen; + screen.blitFrom(_topLine, Common::Point(0, 0)); +} + /** * Update all on-screen sprites to account for any scrolling of the map */ @@ -355,7 +365,55 @@ void Map::updateMap(bool flushScreen) { * Handle moving icon for player from their previous location on the map to a destination location */ void Map::walkTheStreets() { - // TODO + People &people = *_vm->_people; + bool reversePath = false; + Common::Array tempPath; + + // Get indexes into the path lists for the start and destination scenes + int start = _points[_oldCharPoint]._translate; + int dest = _points[_charPoint]._translate; + + // Get pointer to start of path + const int *ptr = &_paths[start][dest]; + + // Check for any intermediate points between the two locations + if (*ptr || _charPoint > 50 || _oldCharPoint > 50) { + people[AL]._sequenceNumber = -1; + + if (_charPoint == 51 || _oldCharPoint == 51) { + people.setWalking(); + } else { + // Check for moving the path backwards or forwards + if (*ptr == 255) { + reversePath = true; + SWAP(start, dest); + ptr = &_paths[start][dest]; + } + + do { + int idx = *ptr++; + tempPath.push_back(_pathPoints[idx - 1] + Common::Point(4, 4)); + } while (*ptr != 254); + + // Load up the path to use + people._walkTo.clear(); + + if (!reversePath) { + people._walkTo = tempPath; + people._walkDest = tempPath[0]; + } else { + for (int idx = 0; idx < ((int)tempPath.size() - 1); ++idx) + people._walkTo.push(tempPath[idx]); + people._walkDest = tempPath[tempPath.size() - 1]; + } + + people._walkDest.x += 12; + people._walkDest.y += 6; + people.setWalking(); + } + } else { + people[AL]._walkCount = 0; + } } /** diff --git a/engines/sherlock/map.h b/engines/sherlock/map.h index 653d8c0084..f324160bce 100644 --- a/engines/sherlock/map.h +++ b/engines/sherlock/map.h @@ -35,13 +35,21 @@ namespace Sherlock { class SherlockEngine; +struct MapEntry : Common::Point { + int _translate; + + MapEntry() : Common::Point(), _translate(-1) {} + + MapEntry(int x, int y, int translate) : Common::Point(x, y), _translate(translate) {} +}; + class Map { private: SherlockEngine *_vm; - Common::Array _points; // Map locations for each scene + Common::Array _points; // Map locations for each scene Common::StringArray _locationNames; Common::Array< Common::Array > _paths; - Common::Array _pathPoints; + Common::Array _pathPoints; Common::Point _savedPos; Common::Point _savedSize; Surface _topLine; @@ -54,7 +62,7 @@ private: Common::Point _lDrawnPos; int _point; bool _placesShown; - int _charPoint; + int _charPoint, _oldCharPoint; int _cursorIndex; bool _drawMap; Surface _iconSave; @@ -67,6 +75,7 @@ private: void showPlaces(); void saveTopLine(); + void eraseTopLine(); void updateMap(bool flushScreen); @@ -77,9 +86,9 @@ private: public: Map(SherlockEngine *vm); - const Common::Point &operator[](int idx) { return _points[idx]; } + const MapEntry &operator[](int idx) { return _points[idx]; } - void loadPoints(int count, const int *xList, const int *yList); + void loadPoints(int count, const int *xList, const int *yList, const int *transList); int show(); }; diff --git a/engines/sherlock/scalpel/darts.cpp b/engines/sherlock/scalpel/darts.cpp index 857ac63f8c..c975cb1086 100644 --- a/engines/sherlock/scalpel/darts.cpp +++ b/engines/sherlock/scalpel/darts.cpp @@ -27,10 +27,395 @@ namespace Sherlock { namespace Scalpel { +enum { + STATUS_INFO_X = 218, + STATUS_INFO_Y = 53, + DART_INFO_X = 218, + DART_INFO_Y = 103, + DARTBARHX = 35, + DARTHORIZY = 190, + DARTBARVX = 1, + DARTHEIGHTY = 25, + DARTBARSIZE = 150, + DART_BAR_FORE = 8 +}; + +enum { + DART_COL_FORE = 5, + PLAYER_COLOR = 11 +}; + +const char *const OPPONENT_NAMES[5] = { + "Skipper", "Willy", "Micky", "Tom", "Bartender" +}; + +/*----------------------------------------------------------------*/ + +Darts::Darts(ScalpelEngine *vm) : _vm(vm) { + _dartImages = nullptr; + _level = 0; + _computerPlayer = 1; + _playerDartMode = false; + _dartScore1 = _dartScore2 = 0; + _roundNumber = 0; + _playerDartMode = false; + _roundScore = 0; + _oldDartButtons = 0; +} + +/** + * Main method for playing darts game + */ void Darts::playDarts() { + Screen &screen = *_vm->_screen; + int score, roundStartScore; + int playerNumber = 0; + int lastDart; + + // Change the font + int oldFont = screen.fontNumber(); + screen.setFont(4); + + loadDarts(); + initDarts(); + + do { + roundStartScore = score = playerNumber == 0 ? _dartScore1 : _dartScore2; + + // Show player details + showNames(playerNumber); + showStatus(playerNumber); + _roundScore = 0; + + for (int idx = 0; idx < 3; ++idx) { + // Throw a single dart + if (_computerPlayer == 1) + lastDart = throwDart(idx + 1, playerNumber * 2); + else if (_computerPlayer == 2) + lastDart = throwDart(idx + 1, playerNumber + 1); + else + lastDart = throwDart(idx + 1, 0); + + score -= lastDart; + _roundScore += lastDart; + + + } + + // todo + } while (!_vm->shouldQuit()); + // TODO } +/** + * Load the graphics needed for the dart game + */ +void Darts::loadDarts() { + Screen &screen = *_vm->_screen; + + _dartImages = new ImageFile("darts.vgs"); + screen._backBuffer1.blitFrom((*_dartImages)[1], Common::Point(0, 0)); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); +} + +/** + * Initializes the variables needed for the dart game + */ +void Darts::initDarts() { + _dartScore1 = _dartScore2 = 301; + _roundNumber = 1; + + if (_level == 9) { + // No computer players + _computerPlayer = 0; + _level = 0; + } else if (_level == 8) { + _level = _vm->getRandomNumber(3); + _computerPlayer = 2; + } else { + // Check flags for opponents + for (int idx = 0; idx < 4; ++idx) { + if (_vm->readFlags(314 + idx)) + _level = idx; + } + } + + _opponent = OPPONENT_NAMES[_level]; +} + +/** + * Show the player names + */ +void Darts::showNames(int playerNum) { + Screen &screen = *_vm->_screen; + byte color = playerNum == 0 ? PLAYER_COLOR : DART_COL_FORE; + + // Print Holmes first + if (playerNum == 0) + screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y), PLAYER_COLOR + 3, "Holmes"); + else + screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y), color, "Holmes"); + + screen._backBuffer1.fillRect(Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10, + STATUS_INFO_X + 31, STATUS_INFO_Y + 12), color); + screen.slamArea(STATUS_INFO_X, STATUS_INFO_Y + 10, 31, 12); + + // Second player + color = playerNum == 1 ? PLAYER_COLOR : DART_COL_FORE; + + if (playerNum != 0) + screen.print(Common::Point(STATUS_INFO_X + 50, STATUS_INFO_Y + 10), PLAYER_COLOR + 3, + _opponent.c_str()); + else + screen.print(Common::Point(STATUS_INFO_X + 50, STATUS_INFO_Y + 10), color, + _opponent.c_str()); + + screen._backBuffer1.fillRect(Common::Rect(STATUS_INFO_X + 50, STATUS_INFO_Y + 10, + STATUS_INFO_Y + 81, STATUS_INFO_Y + 12), color); + screen.slamArea(STATUS_INFO_X + 50, STATUS_INFO_Y + 10, 81, 12); + + // Make a copy of the back buffer to the secondary one + screen._backBuffer2.blitFrom(screen._backBuffer1); +} + +/** + * Show the player score and game status + */ +void Darts::showStatus(int playerNum) { + Screen &screen = *_vm->_screen; + byte color; + + screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 10), + Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10, SHERLOCK_SCREEN_WIDTH, STATUS_INFO_Y + 38)); + + color = (playerNum == 0) ? PLAYER_COLOR : DART_COL_FORE; + screen.print(Common::Point(STATUS_INFO_X + 6, STATUS_INFO_Y + 13), color, "%d", _dartScore1); + + color = (playerNum == 1) ? PLAYER_COLOR : DART_COL_FORE; + screen.print(Common::Point(STATUS_INFO_X + 56, STATUS_INFO_Y + 13), color, "%d", _dartScore2); + screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 25), PLAYER_COLOR, "Round: %d", _roundNumber); + screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 35), PLAYER_COLOR, "Turn Total: %d", _roundScore); + screen.slamRect(Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10, SHERLOCK_SCREEN_WIDTH, STATUS_INFO_Y + 48)); +} + +/** + * Throws a single dart. + * @param dartNum Dart number + * @param computer 0 = Player, 1 = 1st player computer, 2 = 2nd player computer + * @returns Score for what dart hit + */ +int Darts::throwDart(int dartNum, int computer) { + Events &events = *_vm->_events; + Screen &screen = *_vm->_screen; + Common::Point targetNum; + int width, height; + + events.clearKeyboard(); + + erasePowerBars(); + screen.print(Common::Point(DART_INFO_X, DART_INFO_Y), DART_COL_FORE, "Dart # %d", dartNum); + + if (!computer) { + screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 10), DART_COL_FORE, "Hit a key"); + screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 18), DART_COL_FORE, "to start"); + } + + if (!computer) { + while (!_vm->shouldQuit() && !dartHit()) + ; + } else { + events.delay(10); + } + + screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(DART_INFO_X, DART_INFO_Y - 1), + Common::Rect(DART_INFO_X, DART_INFO_Y - 1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + screen.slamRect(Common::Rect(DART_INFO_X, DART_INFO_Y - 1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + + // If it's a computer player, choose a dart destination + if (computer) + targetNum = getComputerDartDest(computer - 1); + + width = doPowerBar(Common::Point(DARTBARHX, DARTHORIZY), DART_BAR_FORE, targetNum.x, 0); + height = 101 - doPowerBar(Common::Point(DARTBARVX, DARTHEIGHTY), DART_BAR_FORE, targetNum.y, 0); + + // For human players, slight y adjustment + if (computer == 0) + height = 2; + + // Copy the bars to the secondary back buffer + screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(DARTBARHX - 1, DARTHORIZY - 1), + Common::Rect(DARTBARHX - 1, DARTHORIZY - 1, DARTBARHX + DARTBARSIZE + 3, DARTHORIZY + 10)); + screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(DARTBARVX - 1, DARTHEIGHTY - 1), + Common::Rect(DARTBARVX - 1, DARTHEIGHTY - 1, DARTBARVX + 11, DARTHEIGHTY + DARTBARSIZE + 3)); + + // Convert to relative range from -49 to 150 + height -= 50; + width -= 50; + + Common::Point dartPos(111 + width * 2, 99 + height * 2); + drawDartThrow(dartPos); + + return dartScore(dartPos); +} + +/** + * Draw a dart moving towards the board + */ +void Darts::drawDartThrow(const Common::Point &pt) { + // TODO +} + +/** + * Erases the power bars + */ +void Darts::erasePowerBars() { + Screen &screen = *_vm->_screen; + + screen._backBuffer1.fillRect(Common::Rect(DARTBARHX, DARTHORIZY, DARTBARHX + DARTBARSIZE, DARTHORIZY + 10), 0); + screen._backBuffer1.fillRect(Common::Rect(DARTBARVX, DARTHEIGHTY, DARTBARVX + 10, DARTHEIGHTY + DARTBARSIZE), 0); + screen._backBuffer1.transBlitFrom((*_dartImages)[3], Common::Point(DARTBARHX - 1, DARTHORIZY - 1)); + screen._backBuffer1.transBlitFrom((*_dartImages)[4], Common::Point(DARTBARVX - 1, DARTHEIGHTY - 1)); + screen.slamArea(DARTBARHX - 1, DARTHORIZY - 1, DARTBARSIZE + 3, 11); + screen.slamArea(DARTBARVX - 1, DARTHEIGHTY - 1, 11, DARTBARSIZE + 3); +} + +/** + * Show a gradually incrementing incrementing power that bar. If goToPower is provided, it will + * increment to that power level ignoring all keyboard input (ie. for computer throws). + * Otherwise, it will increment until either a key/mouse button is pressed, or it reaches the end + */ +int Darts::doPowerBar(const Common::Point &pt, byte color, int goToPower, int orientation) { + // TODO + return 0; +} + +/** + * Returns true if a mouse button or key is pressed. + */ +bool Darts::dartHit() { + Events &events = *_vm->_events; + + if (events.kbHit()) { + events.clearKeyboard(); + return true; + } + + events.setButtonState(); + return events._pressed && !_oldDartButtons; +} + +/** + * Return the score of the given location on the dart-board + */ +int Darts::dartScore(const Common::Point &pt) { + // TODO + return 0; +} + +/** + * Calculates where a computer player is trying to throw their dart, and choose the actual + * point that was hit with some margin of error + */ +Common::Point Darts::getComputerDartDest(int playerNum) { + Common::Point target; + int aim; + int score = playerNum == 0 ? _dartScore1 : _dartScore2; + + if (score > 50) { + // Aim for the bullseye + target.x = target.y = 76; + + if (_level <= 1 && _vm->getRandomNumber(1) == 1) { + // Introduce margin of error + target.x += _vm->getRandomNumber(21) - 10; + target.y += _vm->getRandomNumber(21) - 10; + } + } else { + aim = score; + + bool done; + Common::Point pt; + do { + done = findNumberOnBoard(aim, pt); + --aim; + } while (!done); + + target.x = 75 + ((target.x - 75) * 20 / 27); + target.y = 75 + ((target.y - 75) * 2 / 3); + } + + // Pick a level of accuracy. The higher the level, the more accurate their throw will be + int accuracy = _vm->getRandomNumber(10) + _level * 2; + + if (accuracy <= 2) { + target.x += _vm->getRandomNumber(71) - 35; + target.y += _vm->getRandomNumber(71) - 35; + } else if (accuracy <= 4) { + target.x += _vm->getRandomNumber(51) - 25; + target.y += _vm->getRandomNumber(51) - 25; + } else if (accuracy <= 6) { + target.x += _vm->getRandomNumber(31) - 15; + target.y += _vm->getRandomNumber(31) - 15; + } else if (accuracy <= 8) { + target.x += _vm->getRandomNumber(21) - 10; + target.y += _vm->getRandomNumber(21) - 10; + } else if (accuracy <= 10) { + target.x += _vm->getRandomNumber(11) - 5; + target.y += _vm->getRandomNumber(11) - 5; + } + + if (target.x < 1) + target.x = 1; + if (target.y < 1) + target.y = 1; + + return target; +} + +/** + * Returns the center position for the area of the dartboard with a given number + */ +bool Darts::findNumberOnBoard(int aim, Common::Point &pt) { + ImageFrame &board = (*_dartImages)[2]; + + // Scan board image for the special "center" pixels + bool done = false; + for (int yp = 0; yp < 132 && !done; ++yp) { + const byte *srcP = (const byte *)board._frame.getBasePtr(0, yp); + for (int xp = 0; xp < 147 && !done; ++xp, ++srcP) { + int score = *srcP; + + // Check for match + if (score == aim) { + done = true; + + // Aim at non-double/triple numbers where possible + if (aim < 21) { + pt.x = xp + 5; + pt.y = yp + 5; + + score = *(const byte *)board._frame.getBasePtr(xp + 10, yp + 10); + if (score != aim) + // Not aiming at non-double/triple number yet + done = false; + } else { + // Aiming at a double or triple + pt.x = xp + 3; + pt.y = yp + 3; + } + } + } + } + + if (aim == 3) + pt.x += 15; + pt.y = 132 - pt.y; + + return done; +} + + } // End of namespace Scalpel } // End of namespace Scalpel diff --git a/engines/sherlock/scalpel/darts.h b/engines/sherlock/scalpel/darts.h index 22164156c9..2fbdc3d7e2 100644 --- a/engines/sherlock/scalpel/darts.h +++ b/engines/sherlock/scalpel/darts.h @@ -23,6 +23,8 @@ #ifndef SHERLOCK_DARTS_H #define SHERLOCK_DARTS_H +#include "sherlock/resources.h" + namespace Sherlock { namespace Scalpel { @@ -32,8 +34,37 @@ class ScalpelEngine; class Darts { private: ScalpelEngine *_vm; + ImageFile *_dartImages; + int _dartScore1, _dartScore2; + int _roundNumber; + int _level; + int _computerPlayer; + Common::String _opponent; + bool _playerDartMode; + int _roundScore; + int _oldDartButtons; + + void loadDarts(); + void initDarts(); + + void showNames(int playerNum); + void showStatus(int playerNum); + + int throwDart(int dartNum, int computer); + void drawDartThrow(const Common::Point &pt); + + void erasePowerBars(); + int doPowerBar(const Common::Point &pt, byte color, int goToPower, int orientation); + + bool dartHit(); + int dartScore(const Common::Point &pt); + + Common::Point getComputerDartDest(int playerNum); + + bool findNumberOnBoard(int aim, Common::Point &pt); + public: - Darts(ScalpelEngine *vm) : _vm(vm) {} + Darts(ScalpelEngine *vm); void playDarts(); }; diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 0742d05366..eba6626c53 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -39,6 +39,12 @@ const int MAP_Y[NUM_PLACES] = { 37, 0, 70, 0, 116, 0, 0, 0, 50, 21, 0, 303, 0, 0, 229, 0, 0 }; +int MAP_TRANSLATE[NUM_PLACES] = { + 0, 0, 0, 1, 0, 2, 0, 3, 4, 0, 4, 6, 0, 0, 0, 8, 9, 10, 11, 0, 12, 13, 14, 7, + 15, 16, 17, 18, 19, 0, 20, 21, 22, 23, 0, 24, 0, 25, 0, 26, 0, 0, 0, 27, + 28, 0, 29, 0, 0, 30, 0 +}; + #define MAX_PEOPLE 66 const byte STILL_SEQUENCES[MAX_PEOPLE][MAX_TALK_SEQUENCES] = { @@ -204,7 +210,7 @@ void ScalpelEngine::initialize() { _flags[39] = true; // Turn on Baker Street // Load the map co-ordinates for each scene - _map->loadPoints(NUM_PLACES, &MAP_X[0], &MAP_Y[0]); + _map->loadPoints(NUM_PLACES, &MAP_X[0], &MAP_Y[0], &MAP_TRANSLATE[0]); // Load the inventory loadInventory(); -- cgit v1.2.3 From 6a1b12b797c51bdc51c71db67e2df4e8de6281e0 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Mon, 20 Apr 2015 23:47:34 +0200 Subject: SHERLOCK: Add some more code for the intro --- engines/sherlock/scalpel/scalpel.cpp | 92 ++++++++++++++++++++++++++++++++---- engines/sherlock/scalpel/scalpel.h | 1 + engines/sherlock/sound.cpp | 3 +- engines/sherlock/sound.h | 2 +- 4 files changed, 87 insertions(+), 11 deletions(-) diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index eba6626c53..4e49a6b4d3 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -249,8 +249,8 @@ bool ScalpelEngine::showCityCutscene() { if (finished) { ImageFile titleImages("title2.vgs", true); - _screen->_backBuffer1.blitFrom(*_screen); - _screen->_backBuffer2.blitFrom(*_screen); + _screen->_backBuffer1.copyFrom(*_screen); + _screen->_backBuffer2.copyFrom(*_screen); // London, England _screen->_backBuffer1.transBlitFrom(titleImages[0], Common::Point(10, 11)); @@ -274,8 +274,8 @@ bool ScalpelEngine::showCityCutscene() { if (finished) { ImageFile titleImages("title.vgs", true); - _screen->_backBuffer1.blitFrom(*_screen); - _screen->_backBuffer2.blitFrom(*_screen); + _screen->_backBuffer1.copyFrom(*_screen); + _screen->_backBuffer2.copyFrom(*_screen); // The Lost Files of _screen->_backBuffer1.transBlitFrom(titleImages[0], Common::Point(75, 6)); @@ -320,7 +320,7 @@ bool ScalpelEngine::showAlleyCutscene() { bool finished = _animation->playPrologue("27PRO1", 1, 3, true, 2); if (finished) - _animation->playPrologue("27PRO2", 1, 0, false, 2); + finished = _animation->playPrologue("27PRO2", 1, 0, false, 2); if (finished) { ImageFile screamImages("SCREAM.LBV", false); @@ -330,7 +330,7 @@ bool ScalpelEngine::showAlleyCutscene() { } if (finished) - _animation->playPrologue("27PRO3", 1, 0, true, 2); + finished = _animation->playPrologue("27PRO3", 1, 0, true, 2); if(finished) { _screen->getPalette(palette); @@ -351,13 +351,87 @@ bool ScalpelEngine::showAlleyCutscene() { } bool ScalpelEngine::showStreetCutscene() { - // TODO + _titleOverride = "TITLE.LIB"; + _soundOverride = "TITLE.SND"; + + _sound->playMusic("PROLOG3.MUS"); + + bool finished = _animation->playPrologue("14KICK", 1, 3, true, 2); + + if (finished) + finished = _animation->playPrologue("14NOTE", 1, 0, false, 2); + + _titleOverride = ""; + _soundOverride = ""; + return finished; +} + +bool ScalpelEngine::scrollCredits() { + _titleOverride = "TITLE.LIB"; + ImageFile creditsImages("credits.vgs", true); + + _screen->_backBuffer1.copyFrom(*_screen->_backBuffer); + + for(int i = 0; i < 600 && !_events->kbHit(); i++) { + _screen->_backBuffer1.copyFrom(*_screen->_backBuffer); + if (i < 200) + _screen->transBlitFrom(creditsImages[0], Common::Point(10, -i), false, 0); + if (i > 0 && i < 400) + _screen->transBlitFrom(creditsImages[1], Common::Point(10, 200 - i), false, 0); + if (i > 200) + _screen->transBlitFrom(creditsImages[2], Common::Point(10, 400 - i), false, 0); + + warning("TODO: Use VideoBlockMove"); +// videoblockmove(SCREEN, BACKBUFFER, 0, 0, 320, 10); +// videoblockmove(SCREEN, BACKBUFFER, 0, 190, 320, 10); + + _events->delay(100); + } + + _titleOverride = ""; return true; } bool ScalpelEngine::showOfficeCutscene() { - // TODO - return true; + _sound->playMusic("PROLOG4.MUS"); + _titleOverride = "TITLE2.LIB"; + _soundOverride = "TITLE.SND"; + + bool finished = _animation->playPrologue("COFF1", 1, 3, true, 3); + if (finished) + finished = _animation->playPrologue("COFF2", 1, 0, false, 3); + if (finished) { + warning("TODO: ShowLBV(""NOTE.LBV"");"); + if (_sound->_voices) { + finished = _sound->playSound("NOTE1", WAIT_KBD_OR_FINISH); + if (finished) + finished = _sound->playSound("NOTE2", WAIT_KBD_OR_FINISH); + if (finished) + finished = _sound->playSound("NOTE3", WAIT_KBD_OR_FINISH); + if (finished) + finished = _sound->playSound("NOTE4", WAIT_KBD_OR_FINISH); + } else + finished = _events->delay(19000); + + _events->clearEvents(); + finished = _events->delay(500); + } + + if (finished) + finished = _animation->playPrologue("COFF3", 1, 0, true, 3); + + if (finished) + finished = _animation->playPrologue("COFF4", 1, 0, false, 3); + + if (finished) + finished = scrollCredits(); + + if (finished) + _screen->fadeToBlack(3); + + _titleOverride = ""; + _soundOverride = ""; + return finished; } void ScalpelEngine::loadInventory() { diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h index aa00acab84..194bf5413e 100644 --- a/engines/sherlock/scalpel/scalpel.h +++ b/engines/sherlock/scalpel/scalpel.h @@ -39,6 +39,7 @@ private: bool showAlleyCutscene(); bool showStreetCutscene(); bool showOfficeCutscene(); + bool scrollCredits(); void loadInventory(); protected: diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index c3e50a8be2..600618b570 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -41,8 +41,9 @@ void Sound::loadSound(const Common::String &name, int priority) { // TODO } -void Sound::playSound(const Common::String &name, WaitType waitType) { +bool Sound::playSound(const Common::String &name, WaitType waitType) { // TODO + return true; } void Sound::cacheSound(const Common::String &name, int index) { diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index 22d5a5c221..6adc22c01c 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -52,7 +52,7 @@ public: Sound(SherlockEngine *vm); void loadSound(const Common::String &name, int priority); - void playSound(const Common::String &name, WaitType waitType = WAIT_RETURN_IMMEDIATELY); + bool playSound(const Common::String &name, WaitType waitType = WAIT_RETURN_IMMEDIATELY); void cacheSound(const Common::String &name, int index); void playLoadedSound(int bufNum, int waitMode); void playCachedSound(int index); -- cgit v1.2.3 From 7e1e0ed3ac7ca8b3233503476162c1ca1e79e0a8 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 21 Apr 2015 01:12:16 -0500 Subject: SHERLOCK: More darts game logic --- engines/sherlock/scalpel/darts.cpp | 203 ++++++++++++++++++++++++++++++++++--- engines/sherlock/scalpel/darts.h | 6 +- engines/sherlock/sound.cpp | 3 + engines/sherlock/sound.h | 1 + 4 files changed, 197 insertions(+), 16 deletions(-) diff --git a/engines/sherlock/scalpel/darts.cpp b/engines/sherlock/scalpel/darts.cpp index c975cb1086..c3f2c478d7 100644 --- a/engines/sherlock/scalpel/darts.cpp +++ b/engines/sherlock/scalpel/darts.cpp @@ -67,6 +67,7 @@ Darts::Darts(ScalpelEngine *vm) : _vm(vm) { * Main method for playing darts game */ void Darts::playDarts() { + Events &events = *_vm->_events; Screen &screen = *_vm->_screen; int score, roundStartScore; int playerNumber = 0; @@ -79,6 +80,7 @@ void Darts::playDarts() { loadDarts(); initDarts(); + bool done = false; do { roundStartScore = score = playerNumber == 0 ? _dartScore1 : _dartScore2; @@ -99,13 +101,81 @@ void Darts::playDarts() { score -= lastDart; _roundScore += lastDart; + screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(DART_INFO_X, DART_INFO_Y - 1), + Common::Rect(DART_INFO_X, DART_INFO_Y - 1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + screen.print(Common::Point(DART_INFO_X, DART_INFO_Y), DART_COL_FORE, "Dart # %d", idx + 1); + screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 10), DART_COL_FORE, "Scored %d points", lastDart); + + if (score != 0 && playerNumber == 0) + screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 30), DART_COL_FORE, "Press a key"); + + if (score == 0) { + // Some-one has won + screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 20), PLAYER_COLOR, "GAME OVER!"); + + if (playerNumber == 0) { + screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 30), PLAYER_COLOR, "Holmes Wins!"); + if (_level < 4) + setFlagsForDarts(318 + _level); + } else { + screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 30), PLAYER_COLOR, "%s Wins!", _opponent.c_str()); + } + + screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 4), DART_COL_FORE, "Press a key"); + + idx = 10; + done = true; + } else if (score < 0) { + screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 20), PLAYER_COLOR, "BUSTED!"); + + idx = 10; + score = roundStartScore; + } + + if (playerNumber == 0) + _dartScore1 = score; + else + _dartScore2 = score; + + showStatus(playerNumber); + events.clearKeyboard(); + if ((playerNumber == 0 && _computerPlayer == 1) || _computerPlayer == 0 || done) { + int dartKey; + while (!(dartKey = dartHit()) && !_vm->shouldQuit()) + events.delay(10); + + if (dartKey == Common::KEYCODE_ESCAPE) { + idx = 10; + done = true; + } + } else { + events.wait(20); + } + + screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(DART_INFO_X, DART_INFO_Y - 1), + Common::Rect(DART_INFO_X, DART_INFO_Y - 1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } - // todo - } while (!_vm->shouldQuit()); + playerNumber ^= 1; + if (!playerNumber) + ++_roundNumber; + + done |= _vm->shouldQuit(); - // TODO + if (!done) { + screen._backBuffer2.blitFrom((*_dartImages)[1], Common::Point(0, 0)); + screen._backBuffer1.blitFrom(screen._backBuffer2); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + } + } while (!done); + + closeDarts(); + screen.fadeToBlack(); + + // Restore font + screen.setFont(oldFont); } /** @@ -144,6 +214,14 @@ void Darts::initDarts() { _opponent = OPPONENT_NAMES[_level]; } +/** + * Frees the images used by the dart game + */ +void Darts::closeDarts() { + delete _dartImages; + _dartImages = nullptr; +} + /** * Show the player names */ @@ -236,8 +314,8 @@ int Darts::throwDart(int dartNum, int computer) { if (computer) targetNum = getComputerDartDest(computer - 1); - width = doPowerBar(Common::Point(DARTBARHX, DARTHORIZY), DART_BAR_FORE, targetNum.x, 0); - height = 101 - doPowerBar(Common::Point(DARTBARVX, DARTHEIGHTY), DART_BAR_FORE, targetNum.y, 0); + width = doPowerBar(Common::Point(DARTBARHX, DARTHORIZY), DART_BAR_FORE, targetNum.x, false); + height = 101 - doPowerBar(Common::Point(DARTBARVX, DARTHEIGHTY), DART_BAR_FORE, targetNum.y, true); // For human players, slight y adjustment if (computer == 0) @@ -263,7 +341,43 @@ int Darts::throwDart(int dartNum, int computer) { * Draw a dart moving towards the board */ void Darts::drawDartThrow(const Common::Point &pt) { - // TODO + Events &events = *_vm->_events; + Screen &screen = *_vm->_screen; + Common::Point pos(pt.x, pt.y + 2); + Common::Rect oldDrawBounds; + int delta = 9; + + for (int idx = 5; idx < 24; ++idx) { + Graphics::Surface &frame = (*_dartImages)[idx]._frame; + + // Adjust draw position for animating dart + if (idx < 14) + pos.y -= delta--; + else if (idx == 14) + delta = 1; + else + pos.y += delta++; + + // Draw the dart + Common::Point drawPos(pos.x - frame.w / 2, pos.y - frame.h); + screen._backBuffer1.transBlitFrom(frame, drawPos); + screen.slamArea(drawPos.x, drawPos.y, frame.w, frame.h); + + // Handle erasing old dart + if (!oldDrawBounds.isEmpty()) + screen.slamRect(oldDrawBounds); + + oldDrawBounds = Common::Rect(drawPos.x, drawPos.y, drawPos.x + frame.w, drawPos.y + frame.h); + if (idx != 23) + screen._backBuffer1.blitFrom(screen._backBuffer2, drawPos, oldDrawBounds); + + events.wait(2); + } + + // Draw dart in final "stuck to board" form + screen._backBuffer1.transBlitFrom((*_dartImages)[23], Common::Point(oldDrawBounds.left, oldDrawBounds.top)); + screen._backBuffer2.transBlitFrom((*_dartImages)[23], Common::Point(oldDrawBounds.left, oldDrawBounds.top)); + screen.slamRect(oldDrawBounds); } /** @@ -285,32 +399,86 @@ void Darts::erasePowerBars() { * increment to that power level ignoring all keyboard input (ie. for computer throws). * Otherwise, it will increment until either a key/mouse button is pressed, or it reaches the end */ -int Darts::doPowerBar(const Common::Point &pt, byte color, int goToPower, int orientation) { - // TODO - return 0; +int Darts::doPowerBar(const Common::Point &pt, byte color, int goToPower, bool isVertical) { + Events &events = *_vm->_events; + Screen &screen = *_vm->_screen; + Sound &sound = *_vm->_sound; + bool done; + int idx = 0; + + events.clearEvents(); + if (sound._musicOn) + sound.waitTimerRoland(10); + else + events.delay(100); + + // Display loop + do { + done = _vm->shouldQuit() || idx >= DARTBARSIZE; + + if (idx == (goToPower - 1)) + // Reached target power for a computer player + done = true; + else if (goToPower == 0) { + // Check for pres + if (dartHit()) + done = true; + } + + if (isVertical) { + screen._backBuffer1.hLine(pt.x, pt.y + DARTBARSIZE - 1 - idx, pt.x + 8, color); + screen._backBuffer1.transBlitFrom((*_dartImages)[4], Common::Point(pt.x - 1, pt.y - 1)); + screen.slamArea(pt.x, pt.y + DARTBARSIZE - 1 - idx, 8, 2); + } else { + screen._backBuffer1.vLine(pt.x + idx, pt.y, pt.y + 8, color); + screen._backBuffer1.transBlitFrom((*_dartImages)[3], Common::Point(pt.x - 1, pt.y - 1)); + screen.slamArea(pt.x + idx, pt.y, 1, 8); + } + + if (sound._musicOn) { + if (!(idx % 3)) + sound.waitTimerRoland(1); + } else { + if (!(idx % 8)) + events.wait(1); + } + + ++idx; + } while (!done); + + return MIN(idx * 100 / DARTBARSIZE, 100); } /** * Returns true if a mouse button or key is pressed. */ -bool Darts::dartHit() { +int Darts::dartHit() { Events &events = *_vm->_events; if (events.kbHit()) { + Common::KeyState keyState = events.getKey(); + events.clearKeyboard(); - return true; + return keyState.keycode; } events.setButtonState(); - return events._pressed && !_oldDartButtons; + return events._pressed && !_oldDartButtons ? 1 : 0; } /** * Return the score of the given location on the dart-board */ int Darts::dartScore(const Common::Point &pt) { - // TODO - return 0; + Common::Point pos(pt.x - 37, pt.y - 33); + + if (pos.x < 0 || pos.y < 0 || pos.x >= 147 || pt.y >= 132) + // Not on the board + return 0; + + // On board, so get the score from the pixel at that position + int score = *(const byte *)(*_dartImages)[2]._frame.getBasePtr(pos.x, pos.y); + return score; } /** @@ -415,6 +583,13 @@ bool Darts::findNumberOnBoard(int aim, Common::Point &pt) { return done; } +/** + * Set a global flag to 0 or 1 depending on whether the passed flag is negative or positive. + * @remarks We don't use the global setFlags method because we don't want to check scene flags + */ +void Darts::setFlagsForDarts(int flagNum) { + _vm->_flags[ABS(flagNum)] = flagNum >= 0; +} } // End of namespace Scalpel diff --git a/engines/sherlock/scalpel/darts.h b/engines/sherlock/scalpel/darts.h index 2fbdc3d7e2..a6c8cdba6d 100644 --- a/engines/sherlock/scalpel/darts.h +++ b/engines/sherlock/scalpel/darts.h @@ -46,6 +46,7 @@ private: void loadDarts(); void initDarts(); + void closeDarts(); void showNames(int playerNum); void showStatus(int playerNum); @@ -54,15 +55,16 @@ private: void drawDartThrow(const Common::Point &pt); void erasePowerBars(); - int doPowerBar(const Common::Point &pt, byte color, int goToPower, int orientation); + int doPowerBar(const Common::Point &pt, byte color, int goToPower, bool isVertical); - bool dartHit(); + int dartHit(); int dartScore(const Common::Point &pt); Common::Point getComputerDartDest(int playerNum); bool findNumberOnBoard(int aim, Common::Point &pt); + void setFlagsForDarts(int flagNum); public: Darts(ScalpelEngine *vm); diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index 600618b570..1a6472a9e9 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -95,5 +95,8 @@ void Sound::stopSndFuncPtr(int v1, int v2) { // TODO } +void Sound::waitTimerRoland(uint time) { + // TODO +} } // End of namespace Sherlock diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index 6adc22c01c..28de692109 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -66,6 +66,7 @@ public: void playMusic(const Common::String &name); void stopMusic(); void stopSndFuncPtr(int v1, int v2); + void waitTimerRoland(uint time); }; } // End of namespace Sherlock -- cgit v1.2.3 From 6d2bde38ec883f00b9e4254f869e6349b21e0d28 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 21 Apr 2015 01:26:47 -0500 Subject: SHERLOCK: Fix display of cursor --- engines/sherlock/events.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index 79fe1b58d4..1a827eda3b 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -76,6 +76,7 @@ void Events::setCursor(CursorId cursorId) { */ void Events::setCursor(const Graphics::Surface &src) { CursorMan.replaceCursor(src.getPixels(), src.w, src.h, 0, 0, 0xff); + showCursor(); } /** -- cgit v1.2.3 From a81686b0e1108fc5e9cac79e8e5890ad8c0f8c23 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 21 Apr 2015 02:06:24 -0500 Subject: SHERLOCK: Fix Setup dialog button handling --- engines/sherlock/sherlock.h | 1 - engines/sherlock/user_interface.cpp | 18 +++++++++++------- engines/sherlock/user_interface.h | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 42e2cf8b38..67c7a2864d 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -105,7 +105,6 @@ public: Common::Point _over; // Old map position bool _onChessboard; bool _slowChess; - bool _joystick; int _keyPadSpeed; public: SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc); diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 43ae76f94b..3ab705e26c 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -146,7 +146,8 @@ void Settings::drawInteface(bool flag) { SETUP_POINTS[4][3] - screen.stringWidth(tempStr) / 2, tempStr); screen.makeButton(Common::Rect(SETUP_POINTS[5][0], SETUP_POINTS[5][1], SETUP_POINTS[5][2], SETUP_POINTS[5][1] + 10), SETUP_POINTS[5][3] - screen.stringWidth("New Font Style") / 2, "New Font Style"); - tempStr = Common::String::format("Joystick %s", SETUP_STRS0[_vm->_joystick ? 1 : 0]); + + tempStr = Common::String::format("Joystick %s", SETUP_STRS0[0]); screen.makeButton(Common::Rect(SETUP_POINTS[6][0], SETUP_POINTS[6][1], SETUP_POINTS[6][2], SETUP_POINTS[6][1] + 10), SETUP_POINTS[6][3] - screen.stringWidth(tempStr) / 2, tempStr); screen.makeButton(Common::Rect(SETUP_POINTS[7][0], SETUP_POINTS[7][1], SETUP_POINTS[7][2], SETUP_POINTS[7][1] + 10), @@ -221,7 +222,7 @@ int Settings::drawButtons(const Common::Point &pt, int key) { screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); break; case 6: - tempStr = Common::String::format("Joystick %s", SETUP_STRS0[_vm->_joystick]); + tempStr = Common::String::format("Joystick %s", SETUP_STRS0[0]); screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); break; case 8: @@ -1793,16 +1794,19 @@ void UserInterface::doControls() { if ((found == 5 && events._released) || _key == 'N') { // New font style - screen.setFont((screen.fontNumber() + 1) & 3); - } + int fontNum = screen.fontNumber() + 1; + if (fontNum == 3) + fontNum = 0; - if ((found == 6 && events._released) || _key == 'J') { - // Toggle joystick - _vm->_joystick = !_vm->_joystick; + screen.setFont(fontNum); updateConfig = true; settings.drawInteface(true); } + if ((found == 6 && events._released) || _key == 'J') { + // Toggle joystick - not implemented under ScummVM + } + if ((found == 7 && events._released) || _key == 'C') { // Calibrate joystick - No implementation in ScummVM } diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index 23aca4e536..211287c372 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -67,7 +67,7 @@ class Settings { private: SherlockEngine *_vm; public: - Settings(SherlockEngine *vm) : _vm() {} + Settings(SherlockEngine *vm) : _vm(vm) {} void drawInteface(bool flag); -- cgit v1.2.3 From 6fe65dc719f69c3a3cd3a90426e148972716037f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 21 Apr 2015 03:48:21 -0500 Subject: SHERLOCK: Beginnins of SaveManager class --- engines/sherlock/detection.cpp | 8 +- engines/sherlock/module.mk | 1 + engines/sherlock/saveload.cpp | 183 +++++++++++++++++++++++++++++++++++++++++ engines/sherlock/saveload.h | 74 +++++++++++++++++ 4 files changed, 261 insertions(+), 5 deletions(-) create mode 100644 engines/sherlock/saveload.cpp create mode 100644 engines/sherlock/saveload.h diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp index f207bb69d9..7d9db96e77 100644 --- a/engines/sherlock/detection.cpp +++ b/engines/sherlock/detection.cpp @@ -21,14 +21,13 @@ */ #include "sherlock/sherlock.h" +#include "sherlock/saveload.h" #include "sherlock/scalpel/scalpel.h" #include "sherlock/tattoo/tattoo.h" #include "engines/advancedDetector.h" namespace Sherlock { -#define MAX_SAVES 99 - struct SherlockGameDescription { ADGameDescription desc; @@ -102,12 +101,11 @@ bool SherlockMetaEngine::hasFeature(MetaEngineFeature f) const { } SaveStateList SherlockMetaEngine::listSaves(const char *target) const { - SaveStateList saveList; - return saveList; + return Sherlock::SaveManager(nullptr, "").getSavegameList(target); } int SherlockMetaEngine::getMaximumSaveSlot() const { - return MAX_SAVES; + return NUM_SAVEGAME_SLOTS; } void SherlockMetaEngine::removeSaveState(const char *target, int slot) const { diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk index 171f704a1e..44ba63f1e2 100644 --- a/engines/sherlock/module.mk +++ b/engines/sherlock/module.mk @@ -16,6 +16,7 @@ MODULE_OBJS = \ objects.o \ people.o \ resources.o \ + saveload.o \ scene.o \ screen.o \ sherlock.o \ diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp new file mode 100644 index 0000000000..54995e056a --- /dev/null +++ b/engines/sherlock/saveload.cpp @@ -0,0 +1,183 @@ +/* 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 "sherlock/saveload.h" +#include "sherlock/graphics.h" +#include "sherlock/sherlock.h" +#include "common/system.h" +#include "graphics/scaler.h" +#include "graphics/thumbnail.h" + +namespace Sherlock { + +SaveManager::SaveManager(SherlockEngine *vm, const Common::String &target) : + _vm(vm), _target(target) { + _saveThumb = nullptr; +} + +SaveManager::~SaveManager() { + if (_saveThumb) { + _saveThumb->free(); + delete _saveThumb; + } +} + +/** + * Shows the in-game dialog interface for loading and saving games + */ +void SaveManager::show() { + createSavegameList(); + + // TODO +} + +/** + * Build up a savegame list, with empty slots given an explicit Empty message + */ +void SaveManager::createSavegameList() { + _savegames.clear(); + for (int idx = 0; idx < NUM_SAVEGAME_SLOTS; ++idx) + _savegames.push_back("-EMPTY"); + + SaveStateList saveList = getSavegameList(_target); + for (uint idx = 0; idx < saveList.size(); ++idx) + _savegames[saveList[idx].getSaveSlot()] = saveList[idx].getDescription(); +} + +/** + * Load a list of savegames + */ +SaveStateList SaveManager::getSavegameList(const Common::String &target) { + Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); + Common::StringArray filenames; + Common::String saveDesc; + Common::String pattern = Common::String::format("%s.0??", target.c_str()); + SherlockSavegameHeader header; + + filenames = saveFileMan->listSavefiles(pattern); + sort(filenames.begin(), filenames.end()); // Sort to get the files in numerical order + + SaveStateList saveList; + for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) { + const char *ext = strrchr(file->c_str(), '.'); + int slot = ext ? atoi(ext + 1) : -1; + + if (slot >= 0 && slot < NUM_SAVEGAME_SLOTS) { + Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file); + + if (in) { + readSavegameHeader(in, header); + saveList.push_back(SaveStateDescriptor(slot, header._saveName)); + + header._thumbnail->free(); + delete header._thumbnail; + delete in; + } + } + } + + return saveList; +} + +const char *const SAVEGAME_STR = "SHLK"; +#define SAVEGAME_STR_SIZE 4 + +bool SaveManager::readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header) { + char saveIdentBuffer[SAVEGAME_STR_SIZE + 1]; + header._thumbnail = nullptr; + + // Validate the header Id + in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1); + if (strncmp(saveIdentBuffer, SAVEGAME_STR, SAVEGAME_STR_SIZE)) + return false; + + header._version = in->readByte(); + if (header._version > SHERLOCK_SAVEGAME_VERSION) + return false; + + // Read in the string + header._saveName.clear(); + char ch; + while ((ch = (char)in->readByte()) != '\0') header._saveName += ch; + + // Get the thumbnail + header._thumbnail = Graphics::loadThumbnail(*in); + if (!header._thumbnail) + return false; + + // Read in save date/time + header._year = in->readSint16LE(); + header._month = in->readSint16LE(); + header._day = in->readSint16LE(); + header._hour = in->readSint16LE(); + header._minute = in->readSint16LE(); + header._totalFrames = in->readUint32LE(); + + return true; +} + +void SaveManager::writeSavegameHeader(Common::OutSaveFile *out, SherlockSavegameHeader &header) { + // Write out a savegame header + out->write(SAVEGAME_STR, SAVEGAME_STR_SIZE + 1); + + out->writeByte(SHERLOCK_SAVEGAME_VERSION); + + // Write savegame name + out->write(header._saveName.c_str(), header._saveName.size()); + out->writeByte('\0'); + + // Handle the thumbnail. If there's already one set by the game, create one + if (!_saveThumb) + createThumbnail(); + Graphics::saveThumbnail(*out, *_saveThumb); + + _saveThumb->free(); + delete _saveThumb; + _saveThumb = nullptr; + + // Write out the save date/time + TimeDate td; + g_system->getTimeAndDate(td); + out->writeSint16LE(td.tm_year + 1900); + out->writeSint16LE(td.tm_mon + 1); + out->writeSint16LE(td.tm_mday); + out->writeSint16LE(td.tm_hour); + out->writeSint16LE(td.tm_min); + out->writeUint32LE(_vm->_events->getFrameCounter()); +} + +/** + * Creates a thumbnail for the current on-screen contents + */ +void SaveManager::createThumbnail() { + if (_saveThumb) { + _saveThumb->free(); + delete _saveThumb; + } + + uint8 thumbPalette[PALETTE_SIZE]; + _vm->_screen->getPalette(thumbPalette); + _saveThumb = new Graphics::Surface(); + ::createThumbnail(_saveThumb, (const byte *)_vm->_screen->getPixels(), SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT, thumbPalette); +} + +} // End of namespace Sherlock diff --git a/engines/sherlock/saveload.h b/engines/sherlock/saveload.h new file mode 100644 index 0000000000..a0f1da4041 --- /dev/null +++ b/engines/sherlock/saveload.h @@ -0,0 +1,74 @@ +/* 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 SHERLOCK_SAVELOAD_H +#define SHERLOCK_SAVELOAD_H + +#include "common/scummsys.h" +#include "common/savefile.h" +#include "common/str-array.h" +#include "engines/savestate.h" +#include "graphics/surface.h" + +namespace Sherlock { + +#define NUM_SAVEGAME_SLOTS 99 +#define SHERLOCK_SAVEGAME_VERSION 1 + +struct SherlockSavegameHeader { + uint8 _version; + Common::String _saveName; + Graphics::Surface *_thumbnail; + int _year, _month, _day; + int _hour, _minute; + int _totalFrames; +}; + +class SherlockEngine; + +class SaveManager { +private: + SherlockEngine *_vm; + Common::String _target; + Common::StringArray _savegames; + Graphics::Surface *_saveThumb; + + void createSavegameList(); +public: + SaveManager(SherlockEngine *vm, const Common::String &target); + ~SaveManager(); + + void show(); + + void createThumbnail(); + + static SaveStateList getSavegameList(const Common::String &target); + + void writeSavegameHeader(Common::OutSaveFile *out, SherlockSavegameHeader &header); + + static bool readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header); + +}; + +} // End of namespace Sherlock + +#endif -- cgit v1.2.3 From 31860163709b12a38856fc017a217eb5e32610a7 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 21 Apr 2015 18:25:06 -0500 Subject: SHERLOCK: Implemented save game dialog event handling --- engines/sherlock/detection.cpp | 23 ++- engines/sherlock/saveload.cpp | 185 +++++++++++++++++++- engines/sherlock/saveload.h | 23 ++- engines/sherlock/sherlock.cpp | 3 + engines/sherlock/sherlock.h | 2 + engines/sherlock/user_interface.cpp | 325 ++++++++++++++++++++++++++++++++++-- engines/sherlock/user_interface.h | 3 +- 7 files changed, 540 insertions(+), 24 deletions(-) diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp index 7d9db96e77..bb66cee7df 100644 --- a/engines/sherlock/detection.cpp +++ b/engines/sherlock/detection.cpp @@ -24,6 +24,7 @@ #include "sherlock/saveload.h" #include "sherlock/scalpel/scalpel.h" #include "sherlock/tattoo/tattoo.h" +#include "common/system.h" #include "engines/advancedDetector.h" namespace Sherlock { @@ -105,13 +106,33 @@ SaveStateList SherlockMetaEngine::listSaves(const char *target) const { } int SherlockMetaEngine::getMaximumSaveSlot() const { - return NUM_SAVEGAME_SLOTS; + return MAX_SAVEGAME_SLOTS; } void SherlockMetaEngine::removeSaveState(const char *target, int slot) const { + Common::String filename = Common::String::format("%s.%03d", target, slot); + g_system->getSavefileManager()->removeSavefile(filename); } SaveStateDescriptor SherlockMetaEngine::querySaveMetaInfos(const char *target, int slot) const { + Common::String filename = Common::String::format("%s.%03d", target, slot); + Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(filename); + + if (f) { + Sherlock::SherlockSavegameHeader header; + Sherlock::SaveManager::readSavegameHeader(f, header); + delete f; + + // Create the return descriptor + SaveStateDescriptor desc(slot, header._saveName); + desc.setThumbnail(header._thumbnail); + desc.setSaveDate(header._year, header._month, header._day); + desc.setSaveTime(header._hour, header._minute); + desc.setPlayTime(header._totalFrames * GAME_FRAME_TIME); + + return desc; + } + return SaveStateDescriptor(); } diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index 54995e056a..78c86c836e 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -29,9 +29,21 @@ namespace Sherlock { +const int ENV_POINTS[6][3] = { + { 41, 80, 61 }, // Exit + { 81, 120, 101 }, // Load + { 121, 160, 141 }, // Save + { 161, 200, 181 }, // Up + { 201, 240, 221 }, // Down + { 241, 280, 261 } // Quit +}; + +/*----------------------------------------------------------------*/ + SaveManager::SaveManager(SherlockEngine *vm, const Common::String &target) : _vm(vm), _target(target) { _saveThumb = nullptr; + _envMode = SAVEMODE_NONE; } SaveManager::~SaveManager() { @@ -44,23 +56,80 @@ SaveManager::~SaveManager() { /** * Shows the in-game dialog interface for loading and saving games */ -void SaveManager::show() { +void SaveManager::drawInterface() { + Screen &screen = *_vm->_screen; + UserInterface &ui = *_vm->_ui; + + // Create a list of savegame slots createSavegameList(); - // TODO + screen._backBuffer1.fillRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y + 10), BORDER_COLOR); + screen._backBuffer1.fillRect(Common::Rect(0, CONTROLS_Y + 10, 2, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); + screen._backBuffer1.fillRect(Common::Rect(318, CONTROLS_Y + 10, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); + screen._backBuffer1.fillRect(Common::Rect(0, 199, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); + screen._backBuffer1.fillRect(Common::Rect(2, CONTROLS_Y + 10, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT - 2), INV_BACKGROUND); + + screen.makeButton(Common::Rect(ENV_POINTS[0][0], CONTROLS_Y, ENV_POINTS[0][1], CONTROLS_Y + 10), + ENV_POINTS[0][2] - screen.stringWidth("Exit") / 2, "Exit"); + screen.makeButton(Common::Rect(ENV_POINTS[1][0], CONTROLS_Y, ENV_POINTS[1][1], CONTROLS_Y + 10), + ENV_POINTS[1][2] - screen.stringWidth("Load") / 2, "Load"); + screen.makeButton(Common::Rect(ENV_POINTS[2][0], CONTROLS_Y, ENV_POINTS[2][1], CONTROLS_Y + 10), + ENV_POINTS[2][2] - screen.stringWidth("Save") / 2, "Save"); + screen.makeButton(Common::Rect(ENV_POINTS[3][0], CONTROLS_Y, ENV_POINTS[3][1], CONTROLS_Y + 10), + ENV_POINTS[3][2] - screen.stringWidth("Up") / 2, "Up"); + screen.makeButton(Common::Rect(ENV_POINTS[4][0], CONTROLS_Y, ENV_POINTS[4][1], CONTROLS_Y + 10), + ENV_POINTS[4][2] - screen.stringWidth("Down") / 2, "Down"); + screen.makeButton(Common::Rect(ENV_POINTS[5][0], CONTROLS_Y, ENV_POINTS[5][1], CONTROLS_Y + 10), + ENV_POINTS[5][2] - screen.stringWidth("Quit") / 2, "Quit"); + + if (!_savegameIndex) + screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), COMMAND_NULL, 0, "Up"); + + if (_savegameIndex == MAX_SAVEGAME_SLOTS - 5) + screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), COMMAND_NULL, 0, "Down"); + + for (int idx = _savegameIndex; idx < _savegameIndex + 5; ++idx) + { + screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10), + INV_FOREGROUND, "%d.", idx + 1); + screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10), + INV_FOREGROUND, "%s", _savegames[idx]); + } + + if (!ui._windowStyle) { + screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + } else { + ui.summonWindow(); + } + + _envMode = SAVEMODE_NONE; } /** * Build up a savegame list, with empty slots given an explicit Empty message */ void SaveManager::createSavegameList() { + Screen &screen = *_vm->_screen; + _savegames.clear(); - for (int idx = 0; idx < NUM_SAVEGAME_SLOTS; ++idx) + for (int idx = 0; idx < MAX_SAVEGAME_SLOTS; ++idx) _savegames.push_back("-EMPTY"); SaveStateList saveList = getSavegameList(_target); for (uint idx = 0; idx < saveList.size(); ++idx) _savegames[saveList[idx].getSaveSlot()] = saveList[idx].getDescription(); + + // Ensure the names will fit on the screen + for (uint idx = 0; idx < _savegames.size(); ++idx) { + int width = screen.stringWidth(_savegames[idx]) + 24; + if (width > 308) { + // It won't fit in, so remove characters until it does + do { + width -= screen.charWidth(_savegames[idx].lastChar()); + _savegames[idx].deleteLastChar(); + } while (width > 300); + } + } } /** @@ -81,7 +150,7 @@ SaveStateList SaveManager::getSavegameList(const Common::String &target) { const char *ext = strrchr(file->c_str(), '.'); int slot = ext ? atoi(ext + 1) : -1; - if (slot >= 0 && slot < NUM_SAVEGAME_SLOTS) { + if (slot >= 0 && slot < MAX_SAVEGAME_SLOTS) { Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file); if (in) { @@ -101,6 +170,9 @@ SaveStateList SaveManager::getSavegameList(const Common::String &target) { const char *const SAVEGAME_STR = "SHLK"; #define SAVEGAME_STR_SIZE 4 +/** + * Read in the header information for a savegame + */ bool SaveManager::readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header) { char saveIdentBuffer[SAVEGAME_STR_SIZE + 1]; header._thumbnail = nullptr; @@ -135,6 +207,9 @@ bool SaveManager::readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHea return true; } +/** + * Write out the header information for a savegame + */ void SaveManager::writeSavegameHeader(Common::OutSaveFile *out, SherlockSavegameHeader &header) { // Write out a savegame header out->write(SAVEGAME_STR, SAVEGAME_STR_SIZE + 1); @@ -180,4 +255,106 @@ void SaveManager::createThumbnail() { ::createThumbnail(_saveThumb, (const byte *)_vm->_screen->getPixels(), SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT, thumbPalette); } +/** + * Return the index of the button the mouse is over, if any + */ +int SaveManager::getHighlightedButton() const { + Common::Point pt = _vm->_events->mousePos(); + + for (int idx = 0; idx < 6; ++idx) { + if (pt.x > ENV_POINTS[idx][0] && pt.x < ENV_POINTS[idx][1] && pt.y > CONTROLS_Y + && pt.y < (CONTROLS_Y + 10)) + return idx; + } + + return -1; +} + +/** + * Handle highlighting buttons + */ +void SaveManager::highlightButtons(int btnIndex) { + Screen &screen = *_vm->_screen; + byte color = (btnIndex == 0) ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND; + + screen.buttonPrint(Common::Point(ENV_POINTS[0][2], CONTROLS_Y), color, 1, "Exit"); + + if ((btnIndex == 1) || ((_envMode == 1) && (btnIndex != 2))) + screen.buttonPrint(Common::Point(ENV_POINTS[1][2], CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Load"); + else + screen.buttonPrint(Common::Point(ENV_POINTS[1][2], CONTROLS_Y), COMMAND_FOREGROUND, true, "Load"); + + if ((btnIndex == 2) || ((_envMode == 2) && (btnIndex != 1))) + screen.buttonPrint(Common::Point(ENV_POINTS[2][2], CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Save"); + else + screen.buttonPrint(Common::Point(ENV_POINTS[2][2], CONTROLS_Y), COMMAND_FOREGROUND, true, "Save"); + + if (btnIndex == 3 && _savegameIndex) + screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Up"); + else + if (_savegameIndex) + screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), COMMAND_FOREGROUND, true, "Up"); + + if ((btnIndex == 4) && (_savegameIndex < MAX_SAVEGAME_SLOTS - 5)) + screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Down"); + else if (_savegameIndex < (MAX_SAVEGAME_SLOTS - 5)) + screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), COMMAND_FOREGROUND, true, "Down"); + + color = (btnIndex == 5) ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND; + screen.buttonPrint(Common::Point(ENV_POINTS[5][2], CONTROLS_Y), color, 1, "Quit"); +} + +/** + * Load the game in the specified slot + */ +void SaveManager::loadGame(int slot) { + // TODO +} + +/** + * Save the game in the specified slot with the given name + */ +void SaveManager::saveGame(int slot, const Common::String &name) { + // TODO +} + +/** + * Make sure that the selected savegame is on-screen + */ +bool SaveManager::checkGameOnScreen(int slot) { + Screen &screen = *_vm->_screen; + + // Check if it's already on-screen + if (slot != -1 && (slot < _savegameIndex || slot >= (_savegameIndex + 5))) { + _savegameIndex = slot; + + screen._backBuffer1.fillRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, + SHERLOCK_SCREEN_HEIGHT - 1), INV_BACKGROUND); + + for (int idx = _savegameIndex; idx < (_savegameIndex + 5); ++idx) { + screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10), + INV_FOREGROUND, "%d.", idx + 1); + screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10), + INV_FOREGROUND, "%s", _savegames[idx].c_str()); + } + + screen.slamRect(Common::Rect(3, CONTROLS_Y + 11, 318, SHERLOCK_SCREEN_HEIGHT)); + + byte color = !_savegameIndex ? COMMAND_NULL : COMMAND_FOREGROUND; + screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), color, 1, "Up"); + + color = (_savegameIndex == (MAX_SAVEGAME_SLOTS - 5)) ? COMMAND_NULL : COMMAND_FOREGROUND; + screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), color, 1, "Down"); + + return true; + } + + return false; +} + +bool SaveManager::getFilename(int slot) { + // TODO + return false; +} + } // End of namespace Sherlock diff --git a/engines/sherlock/saveload.h b/engines/sherlock/saveload.h index a0f1da4041..20ce4e6067 100644 --- a/engines/sherlock/saveload.h +++ b/engines/sherlock/saveload.h @@ -31,9 +31,13 @@ namespace Sherlock { -#define NUM_SAVEGAME_SLOTS 99 +#define MAX_SAVEGAME_SLOTS 99 #define SHERLOCK_SAVEGAME_VERSION 1 +enum SaveMode { SAVEMODE_NONE = 0, SAVEMODE_LOAD = 1, SAVEMODE_SAVE = 2 }; + +extern const int ENV_POINTS[6][3]; + struct SherlockSavegameHeader { uint8 _version; Common::String _saveName; @@ -49,15 +53,18 @@ class SaveManager { private: SherlockEngine *_vm; Common::String _target; - Common::StringArray _savegames; Graphics::Surface *_saveThumb; void createSavegameList(); +public: + Common::StringArray _savegames; + int _savegameIndex; + SaveMode _envMode; public: SaveManager(SherlockEngine *vm, const Common::String &target); ~SaveManager(); - void show(); + void drawInterface(); void createThumbnail(); @@ -67,6 +74,16 @@ public: static bool readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header); + int getHighlightedButton() const; + + void highlightButtons(int btnIndex); + + void loadGame(int slot); + void saveGame(int slot, const Common::String &name); + + bool checkGameOnScreen(int slot); + + bool getFilename(int slot); }; } // End of namespace Sherlock diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 632e388642..d0744c4775 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -38,6 +38,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _map = nullptr; _people = nullptr; _res = nullptr; + _saves = nullptr; _scene = nullptr; _screen = nullptr; _sound = nullptr; @@ -58,6 +59,7 @@ SherlockEngine::~SherlockEngine() { delete _journal; delete _map; delete _people; + delete _saves; delete _scene; delete _screen; delete _sound; @@ -83,6 +85,7 @@ void SherlockEngine::initialize() { _map = new Map(this); _journal = new Journal(this); _people = new People(this); + _saves = new SaveManager(this, _targetName); _scene = new Scene(this); _screen = new Screen(this); _sound = new Sound(this); diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 67c7a2864d..20afb6f0e3 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -39,6 +39,7 @@ #include "sherlock/map.h" #include "sherlock/people.h" #include "sherlock/resources.h" +#include "sherlock/saveload.h" #include "sherlock/scene.h" #include "sherlock/screen.h" #include "sherlock/sound.h" @@ -89,6 +90,7 @@ public: Map *_map; People *_people; Resources *_res; + SaveManager *_saves; Scene *_scene; Screen *_screen; Sound *_sound; diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 3ab705e26c..c8cd300b5e 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -65,15 +65,15 @@ const int SETUP_POINTS[12][4] = { { 219, 176, 316, 268 }, // Fade Style { 103, 176, 217, 160 }, // Window Open Style { 4, 176, 101, 53 }, // Portraits Toggle - { 219, 187, 316, 268 } // Key Pad Accel. Toggle + { 219, 187, 316, 268 } // _key Pad Accel. Toggle }; const char COMMANDS[13] = "LMTPOCIUGJFS"; const char INVENTORY_COMMANDS[9] = { "ELUG-+,." }; -const char *const PRESS_KEY_FOR_MORE = "Press any Key for More."; -const char *const PRESS_KEY_TO_CONTINUE = "Press any Key to Continue."; +const char *const PRESS_KEY_FOR_MORE = "Press any _key for More."; +const char *const PRESS_KEY_TO_CONTINUE = "Press any _key to Continue."; const char *const MOPEN[] = { "This cannot be opened", "It is already open", "It is locked", "Wait for Watson", " ", "." @@ -164,7 +164,7 @@ void Settings::drawInteface(bool flag) { tempStr = Common::String::format("Portraits %s", SETUP_STRS0[people._portraitsOn]); screen.makeButton(Common::Rect(SETUP_POINTS[10][0], SETUP_POINTS[10][1], SETUP_POINTS[10][2], SETUP_POINTS[10][1] + 10), SETUP_POINTS[10][3] - screen.stringWidth(tempStr) / 2, tempStr); - tempStr = Common::String::format("Key Pad %s", _vm->_keyPadSpeed ? "Fast" : "Slow"); + tempStr = Common::String::format("_key Pad %s", _vm->_keyPadSpeed ? "Fast" : "Slow"); screen.makeButton(Common::Rect(SETUP_POINTS[11][0], SETUP_POINTS[11][1], SETUP_POINTS[11][2], SETUP_POINTS[11][1] + 10), SETUP_POINTS[11][3] - screen.stringWidth(tempStr) / 2, tempStr); @@ -183,7 +183,7 @@ void Settings::drawInteface(bool flag) { } } -int Settings::drawButtons(const Common::Point &pt, int key) { +int Settings::drawButtons(const Common::Point &pt, int _key) { Events &events = *_vm->_events; People &people = *_vm->_people; Screen &screen = *_vm->_screen; @@ -196,7 +196,7 @@ int Settings::drawButtons(const Common::Point &pt, int key) { for (int idx = 0; idx < 12; ++idx) { if ((pt.x > SETUP_POINTS[idx][0] && pt.x < SETUP_POINTS[idx][2] && pt.y > SETUP_POINTS[idx][1] && pt.y < (SETUP_POINTS[idx][1] + 10) && (events._released || events._released)) - || (key == SETUP_NAMES[idx][0])) { + || (_key == SETUP_NAMES[idx][0])) { found = idx; color = COMMAND_HIGHLIGHTED; } else { @@ -238,7 +238,7 @@ int Settings::drawButtons(const Common::Point &pt, int key) { screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); break; case 11: - tempStr = Common::String::format("Key Pad %s", SETUP_STRS4[_vm->_keyPadSpeed]); + tempStr = Common::String::format("_key Pad %s", SETUP_STRS4[_vm->_keyPadSpeed]); screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); break; default: @@ -328,7 +328,7 @@ void UserInterface::handleInput() { _keycode = Common::KEYCODE_INVALID; // Check kbd and set the mouse released flag if Enter or space is pressed. - // Otherwise, the pressed key is stored for later use + // Otherwise, the pressed _key is stored for later use if (events.kbHit()) { Common::KeyState keyState = events.getKey(); @@ -890,7 +890,304 @@ void UserInterface::lookInv() { * Handles input when the file list window is being displayed */ void UserInterface::doEnvControl() { - // TODO + Events &events = *_vm->_events; + SaveManager &saves = *_vm->_saves; + Scene &scene = *_vm->_scene; + Screen &screen = *_vm->_screen; + Talk &talk = *_vm->_talk; + Common::Point mousePos = events.mousePos(); + static const char ENV_COMMANDS[7] = "ELSUDQ"; + byte color; + + _key = _oldKey = -1; + _keyboardInput = false; + int found = saves.getHighlightedButton(); + + if (events._pressed || events._released) + { + events.clearKeyboard(); + + // Check for a filename entry being highlighted + int found1 = 0; + if ((events._pressed || events._released) && mousePos.y > (CONTROLS_Y + 10)) + { + for (_selector = 0; (_selector < 5) && !found1; ++_selector) + if (mousePos.y > (CONTROLS_Y + 11 + _selector * 10) && mousePos.y < (CONTROLS_Y + 21 + _selector * 10)) + found1 = 1; + + if (_selector + saves._savegameIndex - 1 < MAX_SAVEGAME_SLOTS + (saves._envMode != 1)) + _selector = _selector + saves._savegameIndex - 1; + else + _selector = -1; + + if (!found1) + _selector = -1; + } + + // Handle selecting buttons, if any + saves.highlightButtons(found); + + if (found == 0 || found == 5) + saves._envMode = SAVEMODE_NONE; + } + + if (_keycode) { + _key = toupper(_keycode); + + // Escape _key will close the dialog + if (_key == Common::KEYCODE_ESCAPE) + _key = 'E'; + + if (_key == 'E' || _key == 'L' || _key == 'S' || _key == 'U' || _key == 'D' || _key == 'Q') { + const char *chP = strchr(ENV_COMMANDS, _key); + int btnIndex = !chP ? -1 : chP - ENV_COMMANDS; + saves.highlightButtons(btnIndex); + _keyboardInput = true; + + if (_key == 'E' || _key == 'Q') { + saves._envMode = SAVEMODE_NONE; + } else if (_key >= '1' && _key <= '9') { + _keyboardInput = true; + _selector = _key - '1'; + if (_selector >= MAX_SAVEGAME_SLOTS + (saves._envMode == 1 ? 0 : 1)) + _selector = -1; + + if (saves.checkGameOnScreen(_selector)) + _oldSelector = _selector; + } else { + _selector = -1; + } + } + } + + if (_selector != _oldSelector) { + if (_oldSelector != -1 && _oldSelector >= saves._savegameIndex && _oldSelector < (saves._savegameIndex + 5)) { + screen.print(Common::Point(6, CONTROLS_Y + 12 + (_oldSelector - saves._savegameIndex) * 10), + INV_FOREGROUND, 0, "%d.", _oldSelector + 1); + screen.print(Common::Point(24, CONTROLS_Y + 12 + (_oldSelector - saves._savegameIndex) * 10), + INV_FOREGROUND, 0, "%s", saves._savegames[_oldSelector]); + } + + if (_selector != -1) { + screen.print(Common::Point(6, CONTROLS_Y + 12 + (_selector - saves._savegameIndex) * 10), + TALK_FOREGROUND, 0, "%d.", _selector + 1); + screen.print(Common::Point(24, CONTROLS_Y + 12 + (_selector - saves._savegameIndex) * 10), + TALK_FOREGROUND, 0, "%s", saves._savegames[_selector]); + } + + _oldSelector = _selector; + } + + if (events._released || _keyboardInput) { + if ((found == 0 && events._released) || _key == 'E') { + banishWindow(); + _windowBounds.top = CONTROLS_Y1; + + events._pressed = events._released = _keyboardInput = false; + _keycode = Common::KEYCODE_INVALID; + } else if ((found == 1 && events._released) || _key == 'L') { + saves._envMode = SAVEMODE_LOAD; + if (_selector != -1) { + saves.loadGame(_selector + 1); + } + } else if ((found == 2 && events._released) || _key == 'S') { + saves._envMode = SAVEMODE_SAVE; + if (_selector != -1) { + if (saves.checkGameOnScreen(_selector)) + _oldSelector = _selector; + + if (saves.getFilename(_selector)) { + saves.saveGame(_selector + 1, saves._savegames[_selector]); + + banishWindow(1); + _windowBounds.top = CONTROLS_Y1; + _key = _oldKey = -1; + _keycode = Common::KEYCODE_INVALID; + _keyboardInput = false; + } else { + if (!talk._talkToAbort) { + screen._backBuffer1.fillRect(Common::Rect(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, + SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y + 20 + (_selector - saves._savegameIndex) * 10), INV_BACKGROUND); + screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), INV_FOREGROUND, + "%d.", _selector + 1); + screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), INV_FOREGROUND, + "%s", saves._savegames[_selector]); + + screen.slamArea(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, 311, 10); + _selector = _oldSelector = -1; + } + } + } + } else if (((found == 3 && events._released) || _key == 'U') && saves._savegameIndex) { + bool moreKeys; + do { + saves._savegameIndex--; + screen._backBuffer1.fillRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, + SHERLOCK_SCREEN_HEIGHT - 1), INV_BACKGROUND); + + for (int idx = saves._savegameIndex; idx < (saves._savegameIndex + 5); ++idx) { + color = INV_FOREGROUND; + if (idx == _selector && idx >= saves._savegameIndex && idx < (saves._savegameIndex + 5)) + color = TALK_FOREGROUND; + + screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, "%d.", idx + 1); + screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, "%s", saves._savegames[idx]); + } + + screen.slamRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT)); + + color = !saves._savegameIndex ? COMMAND_NULL : COMMAND_FOREGROUND; + screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), color, true, "Up"); + color = (saves._savegameIndex == MAX_SAVEGAME_SLOTS - 5) ? COMMAND_NULL : COMMAND_FOREGROUND; + screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), color, true, "Down"); + + // Check for there are more pending U keys pressed + moreKeys = false; + if (events.kbHit()) { + Common::KeyState keyState = events.getKey(); + + _key = toupper(keyState.keycode); + moreKeys = _key == 'U'; + } + } while ((saves._savegameIndex) && moreKeys); + } else if (((found == 4 && events._released) || _key == 'D') && saves._savegameIndex < (MAX_SAVEGAME_SLOTS - 5)) { + bool moreKeys; + do { + saves._savegameIndex++; + screen._backBuffer1.fillRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, + SHERLOCK_SCREEN_HEIGHT - 1), INV_BACKGROUND); + + for (int idx = saves._savegameIndex; idx < (saves._savegameIndex + 5); ++idx) { + if (idx == _selector && idx >= saves._savegameIndex && idx < (saves._savegameIndex + 5)) + color = TALK_FOREGROUND; + else + color = INV_FOREGROUND; + + screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, + "%d.", idx + 1); + screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, + "%s", saves._savegames[idx]); + } + + screen.slamRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT)); + + color = (!saves._savegameIndex) ? COMMAND_NULL : COMMAND_FOREGROUND; + screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), color, true, "Up"); + + color = (saves._savegameIndex == MAX_SAVEGAME_SLOTS - 5) ? COMMAND_NULL : COMMAND_FOREGROUND; + screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), color, true, "Down"); + + // Check for there are more pending D keys pressed + moreKeys = false; + if (events.kbHit()) { + Common::KeyState keyState; + _key = toupper(keyState.keycode); + + moreKeys = _key == 'D'; + } + } while (saves._savegameIndex < (MAX_SAVEGAME_SLOTS - 5) && moreKeys); + } else if ((found == 5 && events._released) || _key == 'Q') { + clearWindow(); + screen.print(Common::Point(0, CONTROLS_Y + 20), INV_FOREGROUND, "Are you sure you wish to Quit ?"); + screen.vgaBar(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y + 10), BORDER_COLOR); + + screen.makeButton(Common::Rect(112, CONTROLS_Y, 150, CONTROLS_Y + 10), 136 - screen.stringWidth("Yes") / 2, "Yes"); + screen.makeButton(Common::Rect(161, CONTROLS_Y, 209, CONTROLS_Y + 10), 184 - screen.stringWidth("No") / 2, "No"); + screen.slamArea(112, CONTROLS_Y, 97, 10); + + do { + scene.doBgAnim(); + + if (talk._talkToAbort) + return; + + events.pollEventsAndWait(); + events.setButtonState(); + if (events.kbHit()) { + Common::KeyState keyState = events.getKey(); + _key = toupper(keyState.keycode); + + if (_key == 'X' && (keyState.flags & Common::KBD_ALT) != 0) { + _vm->quitGame(); + events.pollEvents(); + return; + } + + if (_key == Common::KEYCODE_ESCAPE) + _key = 'N'; + + if (_key == Common::KEYCODE_RETURN || _key == Common::KEYCODE_SPACE) { + events._pressed = false; + events._released = true; + events._oldButtons = 0; + _keycode = Common::KEYCODE_INVALID; + } + } + + if (events._pressed || events._released) { + if (mousePos.x > 112 && mousePos.x < 159 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 9)) + color = COMMAND_HIGHLIGHTED; + else + color = COMMAND_FOREGROUND; + screen.buttonPrint(Common::Point(136, CONTROLS_Y), color, true, "Yes"); + + if (mousePos.x > 161 && mousePos.x < 208 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 9)) + color = COMMAND_HIGHLIGHTED; + else + color = COMMAND_FOREGROUND; + screen.buttonPrint(Common::Point(184, CONTROLS_Y), color, true, "No"); + } + + if (mousePos.x > 112 && mousePos.x < 159 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 9) && events._released) + _key = 'Y'; + + if (mousePos.x > 161 && mousePos.x < 208 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 9) && events._released) + _key = 'N'; + } while (!_vm->shouldQuit() && _key != 'Y' && _key != 'N'); + + if (_key == 'Y') { + _vm->quitGame(); + events.pollEvents(); + return; + } else { + screen.buttonPrint(Common::Point(184, CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "No"); + banishWindow(1); + _windowBounds.top = CONTROLS_Y1; + _key = -1; + } + } else { + if (_selector != -1) { + // Are we already in Load mode? + if (saves._envMode == SAVEMODE_LOAD) { + saves.loadGame(_selector + 1); + } else if (saves._envMode == SAVEMODE_SAVE || _selector == MAX_SAVEGAME_SLOTS) { + // We're alreaady in save mode, or pointed to an empty save slot + if (saves.checkGameOnScreen(_selector)) + _oldSelector = _selector; + + if (saves.getFilename(_selector)) { + saves.saveGame(_selector + 1, saves._savegames[_selector]); + banishWindow(); + _windowBounds.top = CONTROLS_Y1; + _key = _oldKey = -1; + _keycode = Common::KEYCODE_INVALID; + _keyboardInput = false; + } else { + if (!talk._talkToAbort) { + screen._backBuffer1.fillRect(Common::Rect(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, + 317, CONTROLS_Y + 20 + (_selector - saves._savegameIndex) * 10), INV_BACKGROUND); + screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), + INV_FOREGROUND, 0, "%d.", _selector + 1); + screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), + INV_FOREGROUND, 0, "%s", saves._savegames[_selector]); + screen.slamArea(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, 311, 10); + _selector = _oldSelector = -1; + } + } + } + } + } + } } /** @@ -1199,6 +1496,7 @@ void UserInterface::doLookControl() { void UserInterface::doMainControl() { Events &events = *_vm->_events; Inventory &inv = *_vm->_inventory; + SaveManager &saves = *_vm->_saves; Common::Point pt = events.mousePos(); if ((events._pressed || events._released) && pt.y > CONTROLS_Y) { @@ -1302,7 +1600,10 @@ void UserInterface::doMainControl() { case 'F': pushButton(10); _menuMode = FILES_MODE; - environment(); + saves.drawInterface(); + + _selector = _oldSelector = -1; + _windowOpen = true; break; case 'S': pushButton(11); @@ -1699,10 +2000,6 @@ void UserInterface::journalControl() { // TODO } -void UserInterface::environment() { - // TODO -} - /** * Handles input when the settings window is being shown */ diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index 211287c372..12470357e5 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -99,7 +99,6 @@ private: bool _lookScriptFlag; Common::Rect _windowBounds; Common::String _descStr; - int _windowStyle; int _find; int _oldUse; private: @@ -124,7 +123,6 @@ private: void doTalkControl(); void journalControl(); - void environment(); void doControls(); void checkUseAction(const UseType *use, const Common::String &invName, const char *const messages[], @@ -138,6 +136,7 @@ public: bool _endKeyActive; int _invLookFlag; int _temp1; + int _windowStyle; public: UserInterface(SherlockEngine *vm); ~UserInterface(); -- cgit v1.2.3 From 0984405a0dbe718522117507d7c75dc619c586a8 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 21 Apr 2015 22:51:03 -0500 Subject: SHERLOCK: Implement savegame synchronization --- engines/sherlock/inventory.cpp | 20 +++++++++++ engines/sherlock/inventory.h | 3 ++ engines/sherlock/journal.cpp | 31 ++++++++++++++++ engines/sherlock/journal.h | 5 +++ engines/sherlock/people.cpp | 13 ++++++- engines/sherlock/people.h | 5 ++- engines/sherlock/saveload.cpp | 71 +++++++++++++++++++++++++++++++++++-- engines/sherlock/saveload.h | 6 ++++ engines/sherlock/scene.cpp | 61 +++++++++++++++++++------------ engines/sherlock/scene.h | 5 ++- engines/sherlock/screen.cpp | 10 ++++++ engines/sherlock/screen.h | 3 ++ engines/sherlock/sherlock.cpp | 10 +++++- engines/sherlock/sherlock.h | 3 +- engines/sherlock/talk.cpp | 12 +++++++ engines/sherlock/talk.h | 6 +++- engines/sherlock/user_interface.cpp | 2 +- 17 files changed, 234 insertions(+), 32 deletions(-) diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index 9eedac7c6a..3ba6f9d2bd 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -486,4 +486,24 @@ int Inventory::deleteItemFromInventory(const Common::String &name) { return 1; } +/** + * Synchronize the data for a savegame + */ +void Inventory::synchronize(Common::Serializer &s) { + s.syncAsSint16LE(_holdings); + + uint count = size(); + s.syncAsUint16LE(count); + if (s.isLoading()) { + resize(count); + + // Reset inventory back to start + _invIndex = 0; + } + + for (uint idx = 0; idx < size(); ++idx) { + // TODO + } +} + } // End of namespace Sherlock diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index 4e426beaf4..bccdc9336e 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -25,6 +25,7 @@ #include "common/scummsys.h" #include "common/array.h" +#include "common/serializer.h" #include "common/str-array.h" #include "sherlock/objects.h" #include "sherlock/resources.h" @@ -99,6 +100,8 @@ public: int putItemInInventory(Object &obj); int deleteItemFromInventory(const Common::String &name); + + void synchronize(Common::Serializer &s); }; } // End of namespace Sherlock diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index f9c2c54289..15d3a07c75 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -1175,4 +1175,35 @@ int Journal::getFindName(bool printError) { return done; } +/** + * Reset viewing position to the start of the journal + */ +void Journal::resetPosition() { + _index = _sub = _up = _down = 0; + _page = 1; +} + +/** + * Synchronize the data for a savegame + */ +void Journal::synchronize(Common::Serializer &s) { + s.syncAsSint16LE(_count); + s.syncAsSint16LE(_index); + s.syncAsSint16LE(_sub); + s.syncAsSint16LE(_page); + s.syncAsSint16LE(_maxPage); + + int journalCount = _journal.size(); + if (s.isLoading()) + _journal.resize(journalCount); + + for (uint idx = 0; idx < _journal.size(); ++idx) { + JournalEntry &je = _journal[idx]; + + s.syncAsSint16LE(je._converseNum); + s.syncAsByte(je._replyOnly); + s.syncAsSint16LE(je._statementNum); + } +} + } // End of namespace Sherlock diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h index 894065759b..9db4b28665 100644 --- a/engines/sherlock/journal.h +++ b/engines/sherlock/journal.h @@ -25,6 +25,7 @@ #include "common/scummsys.h" #include "common/array.h" +#include "common/serializer.h" #include "common/str-array.h" #include "common/stream.h" @@ -77,6 +78,10 @@ public: void drawInterface(); bool handleEvents(int key); + + void resetPosition(); + + void synchronize(Common::Serializer &s); }; } // End of namespace Sherlock diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index d22c08f625..86c560a1d9 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -203,7 +203,7 @@ People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) { _portraitSide = 0; _speakerFlip = false; _holmesFlip = false; - _homesQuotient = 0; + _holmesQuotient = 0; _portrait._sequences = new byte[32]; } @@ -700,4 +700,15 @@ void People::setTalking(int speaker) { } } +/** + * Synchronize the data for a savegame + */ +void People::synchronize(Common::Serializer &s) { + s.syncAsByte(_holmesOn); + s.syncAsSint16LE(_data[AL]._position.x); + s.syncAsSint16LE(_data[AL]._position.y); + s.syncAsSint16LE(_data[AL]._sequenceNumber); + s.syncAsSint16LE(_holmesQuotient); +} + } // End of namespace Sherlock diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index 593b516ee6..94f1d05c0d 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -24,6 +24,7 @@ #define SHERLOCK_PEOPLE_H #include "common/scummsys.h" +#include "common/serializer.h" #include "common/stack.h" #include "sherlock/objects.h" @@ -84,7 +85,7 @@ public: int _portraitSide; bool _speakerFlip; bool _holmesFlip; - int _homesQuotient; + int _holmesQuotient; public: People(SherlockEngine *vm); ~People(); @@ -118,6 +119,8 @@ public: void clearTalking(); void setTalking(int speaker); + + void synchronize(Common::Serializer &s); }; } // End of namespace Sherlock diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index 78c86c836e..0cdf1d228f 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -44,6 +44,7 @@ SaveManager::SaveManager(SherlockEngine *vm, const Common::String &target) : _vm(vm), _target(target) { _saveThumb = nullptr; _envMode = SAVEMODE_NONE; + _justLoaded = false; } SaveManager::~SaveManager() { @@ -308,14 +309,80 @@ void SaveManager::highlightButtons(int btnIndex) { * Load the game in the specified slot */ void SaveManager::loadGame(int slot) { - // TODO + Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading( + generateSaveName(slot)); + Common::Serializer s(saveFile, nullptr); + + // Load the savaegame header + SherlockSavegameHeader header; + if (!readSavegameHeader(saveFile, header)) + error("Invalid savegame"); + + if (header._thumbnail) { + header._thumbnail->free(); + delete header._thumbnail; + } + + // Synchronize the savegame data + synchronize(s); + + delete saveFile; } /** * Save the game in the specified slot with the given name */ void SaveManager::saveGame(int slot, const Common::String &name) { - // TODO + Common::OutSaveFile *out = g_system->getSavefileManager()->openForSaving( + generateSaveName(slot)); + + SherlockSavegameHeader header; + header._saveName = name; + writeSavegameHeader(out, header); + + Common::Serializer s(nullptr, out); + synchronize(s); + + out->finalize(); + delete out; +} + +/** + * Support method that generates a savegame name + * @param slot Slot number + */ +Common::String SaveManager::generateSaveName(int slot) { + return Common::String::format("%s.%03d", _target.c_str(), slot); +} + +/** + * Synchronize the data for a savegame + */ +void SaveManager::synchronize(Common::Serializer &s) { + Journal &journal = *_vm->_journal; + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + Screen &screen = *_vm->_screen; + Talk &talk = *_vm->_talk; + + int oldFont = screen.fontNumber(); + + journal.synchronize(s); + people.synchronize(s); + scene.synchronize(s); + screen.synchronize(s); + talk.synchronize(s); + _vm->synchronize(s); + + if (screen.fontNumber() != oldFont) + journal.resetPosition(); + /* + char room_flags[MAX_ROOMS * 9]; + + */ + + _vm->_loadingSavedGame = true; + _justLoaded = true; } /** diff --git a/engines/sherlock/saveload.h b/engines/sherlock/saveload.h index 20ce4e6067..0dad6256ca 100644 --- a/engines/sherlock/saveload.h +++ b/engines/sherlock/saveload.h @@ -25,6 +25,7 @@ #include "common/scummsys.h" #include "common/savefile.h" +#include "common/serializer.h" #include "common/str-array.h" #include "engines/savestate.h" #include "graphics/surface.h" @@ -56,10 +57,15 @@ private: Graphics::Surface *_saveThumb; void createSavegameList(); + + Common::String generateSaveName(int slot); + + void synchronize(Common::Serializer &s); public: Common::StringArray _savegames; int _savegameIndex; SaveMode _envMode; + bool _justLoaded; public: SaveManager(SherlockEngine *vm, const Common::String &target); ~SaveManager(); diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 575523bc45..4671dbdade 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -85,7 +85,7 @@ void SceneSound::synchronize(Common::SeekableReadStream &s) { Scene::Scene(SherlockEngine *vm): _vm(vm) { for (int idx = 0; idx < SCENES_COUNT; ++idx) - Common::fill(&_stats[idx][0], &_stats[idx][9], false); + Common::fill(&_sceneStats[idx][0], &_sceneStats[idx][65], false); _currentScene = -1; _goToScene = -1; _changes = false; @@ -195,6 +195,7 @@ bool Scene::loadScene(const Common::String &filename) { Events &events = *_vm->_events; Map &map = *_vm->_map; People &people = *_vm->_people; + SaveManager &saves = *_vm->_saves; Screen &screen = *_vm->_screen; Sound &sound = *_vm->_sound; UserInterface &ui = *_vm->_ui; @@ -398,7 +399,7 @@ bool Scene::loadScene(const Common::String &filename) { _changes = false; checkSceneStatus(); - if (!_vm->_justLoaded) { + if (!saves._justLoaded) { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { if (_bgShapes[idx]._type == HIDDEN && _bgShapes[idx]._aType == TALK_EVERY) _bgShapes[idx].toggleHidden(); @@ -450,30 +451,25 @@ bool Scene::loadScene(const Common::String &filename) { * opening or moving them */ void Scene::checkSceneStatus() { - if (_stats[_currentScene][8]) { - for (int idx = 0; idx < 8; ++idx) { - int val = _stats[_currentScene][idx]; + if (_sceneStats[_currentScene][65]) { + for (uint idx = 0; idx < 64; ++idx) { + int val = _sceneStats[_currentScene][idx]; - for (int bit = 0; bit < 8; ++bit) { - uint objNumber = idx * 8 + bit; - if (objNumber < _bgShapes.size()) { - Object &obj = _bgShapes[objNumber]; + if (idx < _bgShapes.size()) { + Object &obj = _bgShapes[idx]; - if (val & 1) { - // No shape to erase, so flag as hidden - obj._type = HIDDEN; - } else if (obj._images == nullptr || obj._images->size() == 0) { - // No shape - obj._type = NO_SHAPE; - } else { - obj._type = ACTIVE_BG_SHAPE; - } + if (val & 1) { + // No shape to erase, so flag as hidden + obj._type = HIDDEN; + } else if (obj._images == nullptr || obj._images->size() == 0) { + // No shape + obj._type = NO_SHAPE; } else { - // Finished checks - return; + obj._type = ACTIVE_BG_SHAPE; } - - val >>= 1; + } else { + // Finished checks + return; } } } @@ -560,6 +556,7 @@ void Scene::checkInventory() { */ void Scene::transitionToScene() { People &people = *_vm->_people; + SaveManager &saves = *_vm->_saves; Screen &screen = *_vm->_screen; Talk &talk = *_vm->_talk; @@ -583,7 +580,7 @@ void Scene::transitionToScene() { // Exit information exists, translate it to real sequence info // Note: If a savegame was just loaded, then the data is already correct. // Otherwise, this is a linked scene or entrance info, and must be translated - if (_hsavedFs < 8 && !_vm->_justLoaded) { + if (_hsavedFs < 8 && !saves._justLoaded) { _hsavedFs = FS_TRANS[_hsavedFs]; _hsavedPos.x *= 100; _hsavedPos.y *= 100; @@ -1457,4 +1454,22 @@ int Scene::closestZone(const Common::Point &pt) { return zone; } +/** + * Synchronize the data for a savegame + */ +void Scene::synchronize(Common::Serializer &s) { + s.syncAsSint16LE(_bigPos.x); + s.syncAsSint16LE(_bigPos.y); + s.syncAsSint16LE(_overPos.x); + s.syncAsSint16LE(_overPos.y); + s.syncAsSint16LE(_oldCharPoint); + s.syncAsSint16LE(_goToScene); + + for (int sceneNum = 0; sceneNum < SCENES_COUNT; ++sceneNum) { + for (int flag = 0; flag < 65; ++flag) { + s.syncAsByte(_sceneStats[sceneNum][flag]); + } + } +} + } // End of namespace Sherlock diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 3549325e8e..cc01fa92ab 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -26,6 +26,7 @@ #include "common/scummsys.h" #include "common/array.h" #include "common/rect.h" +#include "common/serializer.h" #include "sherlock/objects.h" #include "sherlock/resources.h" @@ -104,7 +105,7 @@ public: int _currentScene; int _goToScene; bool _changes; - bool _stats[SCENES_COUNT][9]; + bool _sceneStats[SCENES_COUNT][65]; bool _savedStats[SCENES_COUNT][9]; Common::Point _bigPos; Common::Point _overPos; @@ -167,6 +168,8 @@ public: int closestZone(const Common::Point &pt); void updateBackground(); + + void synchronize(Common::Serializer &s); }; } // End of namespace Sherlock diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index a30108118c..3c9a10e4a1 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -480,4 +480,14 @@ Common::Rect Screen::getDisplayBounds() { return Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } +/** + * Synchronize the data for a savegame + */ +void Screen::synchronize(Common::Serializer &s) { + int fontNumber = _fontNumber; + s.syncAsByte(fontNumber); + if (s.isLoading()) + setFont(fontNumber); +} + } // End of namespace Sherlock diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 2cfd7c8a88..a8bdc53b5a 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -25,6 +25,7 @@ #include "common/list.h" #include "common/rect.h" +#include "common/serializer.h" #include "graphics/surface.h" #include "sherlock/graphics.h" #include "sherlock/resources.h" @@ -128,6 +129,8 @@ public: Common::Rect getDisplayBounds(); int fontNumber() const { return _fontNumber; } + + void synchronize(Common::Serializer &s); }; } // End of namespace Sherlock diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index d0744c4775..bc7b545719 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -45,7 +45,6 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _talk = nullptr; _ui = nullptr; _useEpilogue2 = false; - _justLoaded = false; _loadingSavedGame = false; _onChessboard = false; _slowChess = false; @@ -185,4 +184,13 @@ void SherlockEngine::saveConfig() { // TODO } + +/** + * Synchronize the data for a savegame + */ +void SherlockEngine::synchronize(Common::Serializer &s) { + for (uint idx = 0; idx < _flags.size(); ++idx) + s.syncAsByte(_flags[idx]); +} + } // End of namespace Comet diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 20afb6f0e3..48850fff06 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -101,7 +101,6 @@ public: Common::String _soundOverride; Common::String _titleOverride; bool _useEpilogue2; - bool _justLoaded; bool _loadingSavedGame; int _oldCharPoint; // Old scene Common::Point _over; // Old map position @@ -131,6 +130,8 @@ public: void freeSaveGameList(); void saveConfig(); + + void synchronize(Common::Serializer &s); }; } // End of namespace Sherlock diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 158cae38a9..6740e89efc 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1745,4 +1745,16 @@ void Talk::popStack() { } } +/** + * Synchronize the data for a savegame + */ +void Talk::synchronize(Common::Serializer &s) { + for (int idx = 0; idx < MAX_TALK_FILES; ++idx) { + TalkHistoryEntry &he = _talkHistory[idx]; + + for (int flag = 0; flag < 16; ++flag) + s.syncAsByte(he._data[flag]); + } +} + } // End of namespace Sherlock diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index 4a33f2f557..620a986454 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -26,12 +26,14 @@ #include "common/scummsys.h" #include "common/array.h" #include "common/rect.h" +#include "common/serializer.h" #include "common/stream.h" #include "common/stack.h" namespace Sherlock { #define MAX_TALK_SEQUENCES 11 +#define MAX_TALK_FILES 500 struct SequenceEntry { int _objNum; @@ -93,7 +95,7 @@ private: Common::Stack _sequenceStack; Common::Stack _scriptStack; Common::Array _statements; - TalkHistoryEntry _talkHistory[500]; + TalkHistoryEntry _talkHistory[MAX_TALK_FILES]; int _speaker; int _talkIndex; int _scriptSelect; @@ -145,6 +147,8 @@ public: bool isSequencesEmpty() const { return _scriptStack.empty(); } void popStack(); + + void synchronize(Common::Serializer &s); }; } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index c8cd300b5e..f7f387e9ad 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1820,7 +1820,7 @@ void UserInterface::doTalkControl() { // Add any Holmes point to Holmes' total, if any if (talk._statements[_selector]._quotient) - people._homesQuotient += talk._statements[_selector]._quotient; + people._holmesQuotient += talk._statements[_selector]._quotient; } // Flag the response as having been used -- cgit v1.2.3 From e08520cca94f33cb69ee8058cb08e400e5443016 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 22 Apr 2015 02:32:25 -0500 Subject: SHERLOCK: Fix Files saves listing and save name entry --- engines/sherlock/saveload.cpp | 96 +++++++++++++++++++++++++++++++++++-- engines/sherlock/user_interface.cpp | 17 ++++--- 2 files changed, 102 insertions(+), 11 deletions(-) diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index 0cdf1d228f..57a4a65b21 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -45,6 +45,7 @@ SaveManager::SaveManager(SherlockEngine *vm, const Common::String &target) : _saveThumb = nullptr; _envMode = SAVEMODE_NONE; _justLoaded = false; + _savegameIndex = 0; } SaveManager::~SaveManager() { @@ -94,7 +95,7 @@ void SaveManager::drawInterface() { screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10), INV_FOREGROUND, "%d.", idx + 1); screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10), - INV_FOREGROUND, "%s", _savegames[idx]); + INV_FOREGROUND, "%s", _savegames[idx].c_str()); } if (!ui._windowStyle) { @@ -114,7 +115,7 @@ void SaveManager::createSavegameList() { _savegames.clear(); for (int idx = 0; idx < MAX_SAVEGAME_SLOTS; ++idx) - _savegames.push_back("-EMPTY"); + _savegames.push_back("-EMPTY-"); SaveStateList saveList = getSavegameList(_target); for (uint idx = 0; idx < saveList.size(); ++idx) @@ -420,8 +421,95 @@ bool SaveManager::checkGameOnScreen(int slot) { } bool SaveManager::getFilename(int slot) { - // TODO - return false; + Events &events = *_vm->_events; + Scene &scene = *_vm->_scene; + Screen &screen = *_vm->_screen; + Talk &talk = *_vm->_talk; + int xp, yp; + bool flag = false; + + screen.buttonPrint(Common::Point(ENV_POINTS[0][2], CONTROLS_Y), COMMAND_NULL, true, "Exit"); + screen.buttonPrint(Common::Point(ENV_POINTS[1][2], CONTROLS_Y), COMMAND_NULL, true, "Load"); + screen.buttonPrint(Common::Point(ENV_POINTS[2][2], CONTROLS_Y), COMMAND_NULL, true, "Save"); + screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), COMMAND_NULL, true, "Up"); + screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), COMMAND_NULL, true, "Down"); + screen.buttonPrint(Common::Point(ENV_POINTS[5][2], CONTROLS_Y), COMMAND_NULL, true, "Quit"); + + Common::String saveName = _savegames[slot]; + if (scumm_stricmp(saveName.c_str(), "-EMPTY-") == 0) { + // It's an empty slot, so start off with an empty save name + saveName = ""; + + yp = CONTROLS_Y + 12 + (slot - _savegameIndex) * 10; + screen.vgaBar(Common::Rect(24, yp, 85, yp + 9), INV_BACKGROUND); + } + + screen.print(Common::Point(6, CONTROLS_Y + 12 + (slot - _savegameIndex) * 10), TALK_FOREGROUND, "%d.", slot + 1); + screen.print(Common::Point(24, CONTROLS_Y + 12 + (slot - _savegameIndex) * 10), TALK_FOREGROUND, "%s", saveName.c_str()); + xp = 24 + screen.stringWidth(saveName); + yp = CONTROLS_Y + 12 + (slot - _savegameIndex) * 10; + + int done = 0; + do { + while (!_vm->shouldQuit() && !events.kbHit()) { + scene.doBgAnim(); + + if (talk._talkToAbort) + return false; + + // Allow event processing + events.pollEventsAndWait(); + events.setButtonState(); + + flag = !flag; + if (flag) + screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_FOREGROUND); + else + screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_BACKGROUND); + } + if (_vm->shouldQuit()) + return false; + + // Get the next keypress + Common::KeyState keyState = events.getKey(); + + if (keyState.keycode == Common::KEYCODE_BACKSPACE && saveName.size() > 0) { + // Delete character of save name + screen.vgaBar(Common::Rect(xp - screen.charWidth(saveName.lastChar()), yp - 1, + xp + 8, yp + 9), INV_BACKGROUND); + xp -= screen.charWidth(saveName.lastChar()); + screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_FOREGROUND); + saveName.deleteLastChar(); + } + + if (keyState.keycode == Common::KEYCODE_RETURN) + done = 1; + + if (keyState.keycode == Common::KEYCODE_ESCAPE) { + screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_BACKGROUND); + done = -1; + } + + if (keyState.keycode >= ' ' && keyState.keycode <= 'z' && saveName.size() < 50 + && (xp + screen.charWidth(keyState.keycode)) < 308) { + screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_BACKGROUND); + screen.print(Common::Point(xp, yp), TALK_FOREGROUND, "%c", (char)keyState.keycode); + xp += screen.charWidth((char)keyState.keycode); + screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_FOREGROUND); + saveName += (char)keyState.keycode; + } + } while (!done); + + if (done == 1) { + // Enter key perssed + _savegames[slot] = saveName; + } else { + done = 0; + _envMode = SAVEMODE_NONE; + highlightButtons(-1); + } + + return done == 1; } } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index f7f387e9ad..f95277df91 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -331,13 +331,16 @@ void UserInterface::handleInput() { // Otherwise, the pressed _key is stored for later use if (events.kbHit()) { Common::KeyState keyState = events.getKey(); + _keycode = keyState.keycode; if (keyState.keycode == Common::KEYCODE_x && keyState.flags & Common::KBD_ALT) { _vm->quitGame(); + events.pollEvents(); return; } else if (keyState.keycode == Common::KEYCODE_SPACE || keyState.keycode == Common::KEYCODE_RETURN) { - events._pressed = events._oldButtons = 0; + events._pressed = false; + events._oldButtons = 0; _keycode = Common::KEYCODE_INVALID; } } @@ -963,16 +966,16 @@ void UserInterface::doEnvControl() { if (_selector != _oldSelector) { if (_oldSelector != -1 && _oldSelector >= saves._savegameIndex && _oldSelector < (saves._savegameIndex + 5)) { screen.print(Common::Point(6, CONTROLS_Y + 12 + (_oldSelector - saves._savegameIndex) * 10), - INV_FOREGROUND, 0, "%d.", _oldSelector + 1); + INV_FOREGROUND, "%d.", _oldSelector + 1); screen.print(Common::Point(24, CONTROLS_Y + 12 + (_oldSelector - saves._savegameIndex) * 10), - INV_FOREGROUND, 0, "%s", saves._savegames[_oldSelector]); + INV_FOREGROUND, "%s", saves._savegames[_oldSelector]); } if (_selector != -1) { screen.print(Common::Point(6, CONTROLS_Y + 12 + (_selector - saves._savegameIndex) * 10), - TALK_FOREGROUND, 0, "%d.", _selector + 1); + TALK_FOREGROUND, "%d.", _selector + 1); screen.print(Common::Point(24, CONTROLS_Y + 12 + (_selector - saves._savegameIndex) * 10), - TALK_FOREGROUND, 0, "%s", saves._savegames[_selector]); + TALK_FOREGROUND, "%s", saves._savegames[_selector].c_str()); } _oldSelector = _selector; @@ -1031,7 +1034,7 @@ void UserInterface::doEnvControl() { color = TALK_FOREGROUND; screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, "%d.", idx + 1); - screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, "%s", saves._savegames[idx]); + screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, "%s", saves._savegames[idx].c_str()); } screen.slamRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT)); @@ -1066,7 +1069,7 @@ void UserInterface::doEnvControl() { screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, "%d.", idx + 1); screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, - "%s", saves._savegames[idx]); + "%s", saves._savegames[idx].c_str()); } screen.slamRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT)); -- cgit v1.2.3 From 27938653a5cd05856da88142f52de44f30e26eef Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 22 Apr 2015 04:44:55 -0500 Subject: SHERLOCK: Further fixes for entering savegame names --- engines/sherlock/events.cpp | 12 ++++++++++++ engines/sherlock/events.h | 2 +- engines/sherlock/saveload.cpp | 18 +++++++++++++----- engines/sherlock/user_interface.cpp | 10 +++++----- engines/sherlock/user_interface.h | 2 +- 5 files changed, 32 insertions(+), 12 deletions(-) diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index 1a827eda3b..f7b473ff7a 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -196,6 +196,18 @@ bool Events::checkForNextFrameCounter() { return false; } +/** + * Get a pending keypress + */ +Common::KeyState Events::getKey() { + Common::KeyState keyState = _pendingKeys.pop(); + if ((keyState.flags & Common::KBD_SHIFT) != 0) + keyState.ascii = toupper(keyState.ascii); + + return keyState; +} + + /** * Clear any current keypress or mouse click */ diff --git a/engines/sherlock/events.h b/engines/sherlock/events.h index ccf6eb1c59..015c39580d 100644 --- a/engines/sherlock/events.h +++ b/engines/sherlock/events.h @@ -85,7 +85,7 @@ public: bool kbHit() const { return !_pendingKeys.empty(); } - Common::KeyState getKey() { return _pendingKeys.pop(); } + Common::KeyState getKey(); void clearEvents(); void clearKeyboard(); diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index 57a4a65b21..cd7627a768 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -118,8 +118,11 @@ void SaveManager::createSavegameList() { _savegames.push_back("-EMPTY-"); SaveStateList saveList = getSavegameList(_target); - for (uint idx = 0; idx < saveList.size(); ++idx) - _savegames[saveList[idx].getSaveSlot()] = saveList[idx].getDescription(); + for (uint idx = 0; idx < saveList.size(); ++idx) { + int slot = saveList[idx].getSaveSlot() - 1; + if (slot >= 0 && slot < MAX_SAVEGAME_SLOTS) + _savegames[slot] = saveList[idx].getDescription(); + } // Ensure the names will fit on the screen for (uint idx = 0; idx < _savegames.size(); ++idx) { @@ -312,6 +315,9 @@ void SaveManager::highlightButtons(int btnIndex) { void SaveManager::loadGame(int slot) { Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading( generateSaveName(slot)); + if (!saveFile) + return; + Common::Serializer s(saveFile, nullptr); // Load the savaegame header @@ -492,11 +498,13 @@ bool SaveManager::getFilename(int slot) { if (keyState.keycode >= ' ' && keyState.keycode <= 'z' && saveName.size() < 50 && (xp + screen.charWidth(keyState.keycode)) < 308) { + char c = (char)keyState.ascii; + screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_BACKGROUND); - screen.print(Common::Point(xp, yp), TALK_FOREGROUND, "%c", (char)keyState.keycode); - xp += screen.charWidth((char)keyState.keycode); + screen.print(Common::Point(xp, yp), TALK_FOREGROUND, "%c", c); + xp += screen.charWidth(c); screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_FOREGROUND); - saveName += (char)keyState.keycode; + saveName += c; } } while (!done); diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index f95277df91..cb10606562 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -331,7 +331,7 @@ void UserInterface::handleInput() { // Otherwise, the pressed _key is stored for later use if (events.kbHit()) { Common::KeyState keyState = events.getKey(); - _keycode = keyState.keycode; + _keycode = keyState.ascii; if (keyState.keycode == Common::KEYCODE_x && keyState.flags & Common::KBD_ALT) { _vm->quitGame(); @@ -968,7 +968,7 @@ void UserInterface::doEnvControl() { screen.print(Common::Point(6, CONTROLS_Y + 12 + (_oldSelector - saves._savegameIndex) * 10), INV_FOREGROUND, "%d.", _oldSelector + 1); screen.print(Common::Point(24, CONTROLS_Y + 12 + (_oldSelector - saves._savegameIndex) * 10), - INV_FOREGROUND, "%s", saves._savegames[_oldSelector]); + INV_FOREGROUND, "%s", saves._savegames[_oldSelector].c_str()); } if (_selector != -1) { @@ -1014,7 +1014,7 @@ void UserInterface::doEnvControl() { screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), INV_FOREGROUND, "%d.", _selector + 1); screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), INV_FOREGROUND, - "%s", saves._savegames[_selector]); + "%s", saves._savegames[_selector].c_str()); screen.slamArea(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, 311, 10); _selector = _oldSelector = -1; @@ -1180,9 +1180,9 @@ void UserInterface::doEnvControl() { screen._backBuffer1.fillRect(Common::Rect(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, 317, CONTROLS_Y + 20 + (_selector - saves._savegameIndex) * 10), INV_BACKGROUND); screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), - INV_FOREGROUND, 0, "%d.", _selector + 1); + INV_FOREGROUND, "%d.", _selector + 1); screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), - INV_FOREGROUND, 0, "%s", saves._savegames[_selector]); + INV_FOREGROUND, "%s", saves._savegames[_selector].c_str()); screen.slamArea(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, 311, 10); _selector = _oldSelector = -1; } diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index 12470357e5..99612b218b 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -84,7 +84,7 @@ private: ImageFile *_controls; int _bgFound; int _oldBgFound; - Common::KeyCode _keycode; + int _keycode; int _helpStyle; int _lookHelp; int _help, _oldHelp; -- cgit v1.2.3 From 0fc29972804c12ad9b051574a6e0588ff2b065ee Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 22 Apr 2015 05:06:13 -0500 Subject: SHERLOCK: Fixes for saving and restoring games --- engines/sherlock/events.cpp | 1 + engines/sherlock/scene.cpp | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index f7b473ff7a..f83219d7d2 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -54,6 +54,7 @@ void Events::loadCursors(const Common::String &filename) { delete _cursorImages; _cursorImages = new ImageFile(filename); + _cursorId = INVALID_CURSOR; } /** diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 4671dbdade..316b8739b1 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -1463,7 +1463,11 @@ void Scene::synchronize(Common::Serializer &s) { s.syncAsSint16LE(_overPos.x); s.syncAsSint16LE(_overPos.y); s.syncAsSint16LE(_oldCharPoint); - s.syncAsSint16LE(_goToScene); + + if (s.isSaving()) + s.syncAsSint16LE(_currentScene); + else + s.syncAsSint16LE(_goToScene); for (int sceneNum = 0; sceneNum < SCENES_COUNT; ++sceneNum) { for (int flag = 0; flag < 65; ++flag) { -- cgit v1.2.3 From 8b0e8cd505eebf199aa9888ce65012f1574b1233 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 22 Apr 2015 06:25:04 -0500 Subject: SHERLOCK: Hook up savegames to launcher --- engines/sherlock/detection.cpp | 13 +++++++++---- engines/sherlock/journal.cpp | 1 + engines/sherlock/saveload.cpp | 4 ++-- engines/sherlock/saveload.h | 4 ++-- engines/sherlock/sherlock.cpp | 18 ++++++++++++++++-- engines/sherlock/sherlock.h | 1 + 6 files changed, 31 insertions(+), 10 deletions(-) diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp index bb66cee7df..5d217bd1c5 100644 --- a/engines/sherlock/detection.cpp +++ b/engines/sherlock/detection.cpp @@ -98,7 +98,12 @@ bool SherlockMetaEngine::createInstance(OSystem *syst, Engine **engine, const AD } bool SherlockMetaEngine::hasFeature(MetaEngineFeature f) const { - return false; + return + (f == kSupportsListSaves) || + (f == kSupportsLoadingDuringStartup) || + (f == kSupportsDeleteSave) || + (f == kSavesSupportMetaInfo) || + (f == kSavesSupportThumbnail); } SaveStateList SherlockMetaEngine::listSaves(const char *target) const { @@ -109,13 +114,13 @@ int SherlockMetaEngine::getMaximumSaveSlot() const { return MAX_SAVEGAME_SLOTS; } -void SherlockMetaEngine::removeSaveState(const char *target, int slot) const { - Common::String filename = Common::String::format("%s.%03d", target, slot); +void SherlockMetaEngine::removeSaveState(const char *target, int slot) const { + Common::String filename = Sherlock::SaveManager(nullptr, target).generateSaveName(slot); g_system->getSavefileManager()->removeSavefile(filename); } SaveStateDescriptor SherlockMetaEngine::querySaveMetaInfos(const char *target, int slot) const { - Common::String filename = Common::String::format("%s.%03d", target, slot); + Common::String filename = Sherlock::SaveManager(nullptr, target).generateSaveName(slot); Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(filename); if (f) { diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 15d3a07c75..18edec8c73 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -1194,6 +1194,7 @@ void Journal::synchronize(Common::Serializer &s) { s.syncAsSint16LE(_maxPage); int journalCount = _journal.size(); + s.syncAsUint16LE(journalCount); if (s.isLoading()) _journal.resize(journalCount); diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index cd7627a768..207eff1ab4 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -318,8 +318,6 @@ void SaveManager::loadGame(int slot) { if (!saveFile) return; - Common::Serializer s(saveFile, nullptr); - // Load the savaegame header SherlockSavegameHeader header; if (!readSavegameHeader(saveFile, header)) @@ -331,6 +329,7 @@ void SaveManager::loadGame(int slot) { } // Synchronize the savegame data + Common::Serializer s(saveFile, nullptr); synchronize(s); delete saveFile; @@ -347,6 +346,7 @@ void SaveManager::saveGame(int slot, const Common::String &name) { header._saveName = name; writeSavegameHeader(out, header); + // Synchronize the savegame data Common::Serializer s(nullptr, out); synchronize(s); diff --git a/engines/sherlock/saveload.h b/engines/sherlock/saveload.h index 0dad6256ca..0865fd3856 100644 --- a/engines/sherlock/saveload.h +++ b/engines/sherlock/saveload.h @@ -58,8 +58,6 @@ private: void createSavegameList(); - Common::String generateSaveName(int slot); - void synchronize(Common::Serializer &s); public: Common::StringArray _savegames; @@ -76,6 +74,8 @@ public: static SaveStateList getSavegameList(const Common::String &target); + Common::String generateSaveName(int slot); + void writeSavegameHeader(Common::OutSaveFile *out, SherlockSavegameHeader &header); static bool readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header); diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index bc7b545719..cd5d48033a 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -23,6 +23,7 @@ #include "sherlock/sherlock.h" #include "sherlock/graphics.h" #include "common/scummsys.h" +#include "common/config-manager.h" #include "common/debug-channels.h" #include "engines/util.h" @@ -49,6 +50,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _onChessboard = false; _slowChess = false; _keyPadSpeed = 0; + _loadGameSlot = -1; } SherlockEngine::~SherlockEngine() { @@ -95,8 +97,20 @@ void SherlockEngine::initialize() { Common::Error SherlockEngine::run() { initialize(); - // Temporarily disabled for now -// showOpening(); + // If requested, load a savegame instead of showing the intro + if (ConfMan.hasKey("save_slot")) { + int saveSlot = ConfMan.getInt("save_slot"); + if (saveSlot >= 1 && saveSlot <= MAX_SAVEGAME_SLOTS) + _loadGameSlot = saveSlot; + } + + if (_loadGameSlot != -1) { + _saves->loadGame(_loadGameSlot); + _loadGameSlot = -1; + } else { + // Temporarily disabled for now + // showOpening(); + } while (!shouldQuit()) { // Prepare for scene, and handle any game-specific scenes. This allows diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 48850fff06..09e969884c 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -107,6 +107,7 @@ public: bool _onChessboard; bool _slowChess; int _keyPadSpeed; + int _loadGameSlot; public: SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc); virtual ~SherlockEngine(); -- cgit v1.2.3 From acf0b01ad80acb54992a36c0123f3c951e2200e3 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 22 Apr 2015 07:08:01 -0500 Subject: SHERLOCK: Hook up saving and loading via GMM --- engines/sherlock/detection.cpp | 7 +++++++ engines/sherlock/saveload.cpp | 4 ---- engines/sherlock/sherlock.cpp | 43 ++++++++++++++++++++++++++++++++++++------ engines/sherlock/sherlock.h | 10 ++++++++-- 4 files changed, 52 insertions(+), 12 deletions(-) diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp index 5d217bd1c5..c4d1c65fd5 100644 --- a/engines/sherlock/detection.cpp +++ b/engines/sherlock/detection.cpp @@ -106,6 +106,13 @@ bool SherlockMetaEngine::hasFeature(MetaEngineFeature f) const { (f == kSavesSupportThumbnail); } +bool Sherlock::SherlockEngine::hasFeature(EngineFeature f) const { + return + (f == kSupportsRTL) || + (f == kSupportsLoadingDuringRuntime) || + (f == kSupportsSavingDuringRuntime); +} + SaveStateList SherlockMetaEngine::listSaves(const char *target) const { return Sherlock::SaveManager(nullptr, "").getSavegameList(target); } diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index 207eff1ab4..7610c42d8c 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -383,10 +383,6 @@ void SaveManager::synchronize(Common::Serializer &s) { if (screen.fontNumber() != oldFont) journal.resetPosition(); - /* - char room_flags[MAX_ROOMS * 9]; - - */ _vm->_loadingSavedGame = true; _justLoaded = true; diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index cd5d48033a..518a7aa86b 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -51,6 +51,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _slowChess = false; _keyPadSpeed = 0; _loadGameSlot = -1; + _canLoadSave = false; } SherlockEngine::~SherlockEngine() { @@ -147,8 +148,11 @@ void SherlockEngine::sceneLoop() { // Handle any input from the keyboard or mouse handleInput(); - if (_scene->_hsavedPos.x == -1) + if (_scene->_hsavedPos.x == -1) { + _canLoadSave = true; _scene->doBgAnim(); + _canLoadSave = false; + } } _scene->freeScene(); @@ -160,7 +164,9 @@ void SherlockEngine::sceneLoop() { * Handle all player input */ void SherlockEngine::handleInput() { + _canLoadSave = true; _events->pollEventsAndWait(); + _canLoadSave = false; // See if a key or mouse button is pressed _events->setButtonState(); @@ -190,15 +196,10 @@ void SherlockEngine::setFlags(int flagNum) { _scene->checkSceneFlags(true); } -void SherlockEngine::freeSaveGameList() { - // TODO -} - void SherlockEngine::saveConfig() { // TODO } - /** * Synchronize the data for a savegame */ @@ -207,4 +208,34 @@ void SherlockEngine::synchronize(Common::Serializer &s) { s.syncAsByte(_flags[idx]); } +/** + * Returns true if a savegame can be loaded + */ +bool SherlockEngine::canLoadGameStateCurrently() { + return _canLoadSave; +} + +/** + * Returns true if the game can be saved + */ +bool SherlockEngine::canSaveGameStateCurrently() { + return _canLoadSave; +} + +/** + * Called by the GMM to load a savegame + */ +Common::Error SherlockEngine::loadGameState(int slot) { + _saves->loadGame(slot); + return Common::kNoError; +} + +/** + * Called by the GMM to save the game + */ +Common::Error SherlockEngine::saveGameState(int slot, const Common::String &desc) { + _saves->saveGame(slot, desc); + return Common::kNoError; +} + } // End of namespace Comet diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 09e969884c..916c9cd253 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -80,6 +80,8 @@ protected: virtual void showOpening() = 0; virtual void startScene() {} + + virtual bool hasFeature(EngineFeature f) const; public: const SherlockGameDescription *_gameDescription; Animation *_animation; @@ -108,12 +110,18 @@ public: bool _slowChess; int _keyPadSpeed; int _loadGameSlot; + bool _canLoadSave; public: SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc); virtual ~SherlockEngine(); virtual Common::Error run(); + virtual bool canLoadGameStateCurrently(); + virtual bool canSaveGameStateCurrently(); + virtual Common::Error loadGameState(int slot); + virtual Common::Error saveGameState(int slot, const Common::String &desc); + int getGameType() const; uint32 getGameID() const; uint32 getGameFeatures() const; @@ -128,8 +136,6 @@ public: void setFlags(int flagNum); - void freeSaveGameList(); - void saveConfig(); void synchronize(Common::Serializer &s); -- cgit v1.2.3 From 4f04f90a97965e278f5cbda6fbbd36fa493655cb Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 22 Apr 2015 07:14:49 -0500 Subject: SHERLOCK: Fix thumbnails for savegames made via in-game files dialog --- engines/sherlock/user_interface.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index cb10606562..a3631c577d 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1603,6 +1603,12 @@ void UserInterface::doMainControl() { case 'F': pushButton(10); _menuMode = FILES_MODE; + + // Create a thumbnail of the current screen before the files dialog is shown, in case + // the user saves the game + saves.createThumbnail(); + + // Display the dialog saves.drawInterface(); _selector = _oldSelector = -1; -- cgit v1.2.3 From 214cd61afd6ab60f749263a54127dfbd629147dd Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 22 Apr 2015 17:23:14 -0500 Subject: SHERLOCK: Fixes for multi-point walking routes --- engines/sherlock/map.cpp | 6 ++++-- engines/sherlock/objects.cpp | 2 +- engines/sherlock/people.cpp | 18 +++++++++--------- engines/sherlock/people.h | 4 ++-- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index 6fd169f43a..6fff48a1d3 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -399,8 +399,10 @@ void Map::walkTheStreets() { people._walkTo.clear(); if (!reversePath) { - people._walkTo = tempPath; - people._walkDest = tempPath[0]; + for (int idx = 0; idx < (int)tempPath.size(); ++idx) + people._walkTo.push(tempPath[idx]); + + people._walkDest = tempPath.front(); } else { for (int idx = 0; idx < ((int)tempPath.size() - 1); ++idx) people._walkTo.push(tempPath[idx]); diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 82daa90a38..ec8bb4f551 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -291,7 +291,7 @@ void Sprite::checkSprite() { break; case WALK_AROUND: - if (objBounds.contains(people._walkTo.top())) { + if (objBounds.contains(people._walkTo.front())) { // Reached zone people.gotoStand(*this); } else { diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 86c560a1d9..0212be69b2 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -554,7 +554,7 @@ void People::goAllTheWay() { ++i; // See how many points there are between the src and dest zones - if (!count || count == 255) { + if (!count || count == -1) { // There are none, so just walk to the new zone setWalking(); } else { @@ -563,22 +563,22 @@ void People::goAllTheWay() { _walkTo.clear(); if (scene._walkDirectory[_srcZone][_destZone] != -1) { - for (int idx = 0; idx < count; ++idx, i += 3) { + i += 3 * (count - 1); + for (int idx = 0; idx < count; ++idx, i -= 3) { _walkTo.push(Common::Point(READ_LE_UINT16(&scene._walkData[i]), scene._walkData[i + 2])); } } else { - for (int idx = 0; idx < count; ++idx) - _walkTo.push(Common::Point()); - - for (int idx = count - 1; idx >= 0; --idx, i += 3) { - _walkTo[idx].x = READ_LE_UINT16(&scene._walkData[i]); - _walkTo[idx].y = scene._walkData[i + 2]; + for (int idx = 0; idx < count; ++idx, i += 3) { + _walkTo.push(Common::Point(READ_LE_UINT16(&scene._walkData[i]), scene._walkData[i + 2])); } } + // Final position + _walkTo.push(_walkDest); + // Start walking - _walkDest = _walkTo.top(); + _walkDest = _walkTo.pop(); setWalking(); } } diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index 94f1d05c0d..8a7476a33a 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -25,7 +25,7 @@ #include "common/scummsys.h" #include "common/serializer.h" -#include "common/stack.h" +#include "common/queue.h" #include "sherlock/objects.h" namespace Sherlock { @@ -74,7 +74,7 @@ private: public: ImageFile *_talkPics; Common::Point _walkDest; - Common::Stack _walkTo; + Common::Queue _walkTo; Person &_player; bool _holmesOn; bool _portraitLoaded; -- cgit v1.2.3 From 0a4b722b5d348ba38ab4161cac06597506cbe6cf Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 22 Apr 2015 17:36:50 -0500 Subject: SHERLOCK: Fix leaving scenes via exit zones --- engines/sherlock/objects.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index ec8bb4f551..a1ead2c437 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -161,11 +161,15 @@ void Sprite::adjustSprite() { Exit *exit = scene.checkForExit(charRect); if (exit) { - scene._hsavedPos = exit->_people; - scene._hsavedFs = exit->_peopleDir; + scene._goToScene = exit->_scene; - if (scene._hsavedFs > 100 && scene._hsavedPos.x < 1) - scene._hsavedPos.x = 100; + if (exit->_people.x != 0) { + scene._hsavedPos = exit->_people; + scene._hsavedFs = exit->_peopleDir; + + if (scene._hsavedFs > 100 && scene._hsavedPos.x < 1) + scene._hsavedPos.x = 100; + } } } } -- cgit v1.2.3 From afbc333696c11a5a10bd6aa1061eded92836c751 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 22 Apr 2015 18:41:40 -0500 Subject: SHERLOCK: Fix display of overhead map --- engines/sherlock/map.cpp | 33 +++++++++++++++++++++------------ engines/sherlock/map.h | 3 ++- engines/sherlock/scalpel/scalpel.cpp | 11 +++++++++-- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index 6fff48a1d3..e07dedf7dd 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -34,7 +34,7 @@ Map::Map(SherlockEngine *vm): _vm(vm), _topLine(SHERLOCK_SCREEN_WIDTH, 12) { _charPoint = _oldCharPoint = -1; _cursorIndex = -1; _drawMap = false; - for (int idx = 0; idx < 3; ++idx) + for (int idx = 0; idx < MAX_HOLMES_SEQUENCE; ++idx) Common::fill(&_sequences[idx][0], &_sequences[idx][MAX_FRAME], 0); loadData(); @@ -49,6 +49,15 @@ void Map::loadPoints(int count, const int *xList, const int *yList, const int *t } } +/** + * Load the sequence data for player icon animations + */ +void Map::loadSequences(int count, const byte *seq) { + for (int idx = 0; idx < count; ++idx, seq += MAX_FRAME) + Common::copy(seq, seq + MAX_FRAME, &_sequences[idx][0]); +} + + /** * Load data needed for the map */ @@ -108,10 +117,10 @@ int Map::show() { // Load need sprites setupSprites(); - screen._backBuffer1.blitFrom(bigMap[1], Common::Point(-_bigPos.x, -_bigPos.y)); - screen._backBuffer1.blitFrom(bigMap[2], Common::Point(-_bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y)); - screen._backBuffer1.blitFrom(bigMap[3], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, -_bigPos.y)); - screen._backBuffer1.blitFrom(bigMap[4], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y)); + screen._backBuffer1.blitFrom(bigMap[0], Common::Point(-_bigPos.x, -_bigPos.y)); + screen._backBuffer1.blitFrom(bigMap[1], Common::Point(-_bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y)); + screen._backBuffer1.blitFrom(bigMap[2], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, -_bigPos.y)); + screen._backBuffer1.blitFrom(bigMap[3], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y)); _drawMap = true; _point = -1; @@ -168,10 +177,10 @@ int Map::show() { // Map has scrolled, so redraw new map view changed = false; - screen._backBuffer1.blitFrom(bigMap[1], Common::Point(-_bigPos.x, -_bigPos.y)); - screen._backBuffer1.blitFrom(bigMap[2], Common::Point(-_bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y)); - screen._backBuffer1.blitFrom(bigMap[3], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, -_bigPos.y)); - screen._backBuffer1.blitFrom(bigMap[4], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y)); + screen._backBuffer1.blitFrom(bigMap[0], Common::Point(-_bigPos.x, -_bigPos.y)); + screen._backBuffer1.blitFrom(bigMap[1], Common::Point(-_bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y)); + screen._backBuffer1.blitFrom(bigMap[2], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, -_bigPos.y)); + screen._backBuffer1.blitFrom(bigMap[3], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y)); showPlaces(); _placesShown = false; @@ -249,7 +258,7 @@ void Map::setupSprites() { p._type = CHARACTER; p._position = Common::Point(12400, 5000); p._sequenceNumber = 0; - p._sequences = (Sequences *)&_sequences; + p._sequences = &_sequences; p._images = _shapes; p._imageFrame = nullptr; p._frameNumber = 0; @@ -283,13 +292,13 @@ void Map::showPlaces() { Screen &screen = *_vm->_screen; for (uint idx = 0; idx < _points.size(); ++idx) { - const Common::Point &pt = _points[idx]; + const MapEntry &pt = _points[idx]; if (pt.x != 0 && pt.y != 0) { if (pt.x >= _bigPos.x && (pt.x - _bigPos.x) < SHERLOCK_SCREEN_WIDTH && pt.y >= _bigPos.y && (pt.y - _bigPos.y) < SHERLOCK_SCREEN_HEIGHT) { if (_vm->readFlags(idx)) { - screen._backBuffer1.transBlitFrom((*_iconShapes)[idx], + screen._backBuffer1.transBlitFrom((*_iconShapes)[pt._translate], Common::Point(pt.x - _bigPos.x - 6, pt.y - _bigPos.y - 12)); } } diff --git a/engines/sherlock/map.h b/engines/sherlock/map.h index f324160bce..5b63fe768c 100644 --- a/engines/sherlock/map.h +++ b/engines/sherlock/map.h @@ -56,7 +56,7 @@ private: ImageFile *_mapCursors; ImageFile *_shapes; ImageFile *_iconShapes; - byte _sequences[3][MAX_FRAME]; + byte _sequences[MAX_HOLMES_SEQUENCE][MAX_FRAME]; Common::Point _bigPos; Common::Point _overPos; Common::Point _lDrawnPos; @@ -89,6 +89,7 @@ public: const MapEntry &operator[](int idx) { return _points[idx]; } void loadPoints(int count, const int *xList, const int *yList, const int *transList); + void loadSequences(int count, const byte *seq); int show(); }; diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 4e49a6b4d3..2ca9f80c42 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -39,12 +39,18 @@ const int MAP_Y[NUM_PLACES] = { 37, 0, 70, 0, 116, 0, 0, 0, 50, 21, 0, 303, 0, 0, 229, 0, 0 }; -int MAP_TRANSLATE[NUM_PLACES] = { +const int MAP_TRANSLATE[NUM_PLACES] = { 0, 0, 0, 1, 0, 2, 0, 3, 4, 0, 4, 6, 0, 0, 0, 8, 9, 10, 11, 0, 12, 13, 14, 7, 15, 16, 17, 18, 19, 0, 20, 21, 22, 23, 0, 24, 0, 25, 0, 26, 0, 0, 0, 27, 28, 0, 29, 0, 0, 30, 0 }; +const byte MAP_SEQUENCES[3][MAX_FRAME] = { + { 1, 1, 2, 3, 4, 0 }, // Overview Still + { 5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 0 }, + { 5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 0 } +}; + #define MAX_PEOPLE 66 const byte STILL_SEQUENCES[MAX_PEOPLE][MAX_TALK_SEQUENCES] = { @@ -209,8 +215,9 @@ void ScalpelEngine::initialize() { _flags[3] = true; // Turn on Alley _flags[39] = true; // Turn on Baker Street - // Load the map co-ordinates for each scene + // Load the map co-ordinates for each scene and sequence data _map->loadPoints(NUM_PLACES, &MAP_X[0], &MAP_Y[0], &MAP_TRANSLATE[0]); + _map->loadSequences(3, &MAP_SEQUENCES[0][0]); // Load the inventory loadInventory(); -- cgit v1.2.3 From 1ae176f3eb2e392d400095d734895728f0a5eabc Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 22 Apr 2015 19:44:57 -0500 Subject: SHERLOCK: Fix display of location names on overhead map --- engines/sherlock/map.cpp | 74 ++++++++++++++++++++++++++++++++++++++++++++++++ engines/sherlock/map.h | 3 ++ 2 files changed, 77 insertions(+) diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index e07dedf7dd..b89b4b29fa 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -113,6 +113,7 @@ int Map::show() { // Load the entire map ImageFile bigMap("bigmap.vgs"); + screen.setPalette(bigMap._palette); // Load need sprites setupSprites(); @@ -194,6 +195,10 @@ int Map::show() { _placesShown = true; } + if (_cursorIndex == 0) { + Common::Point pt = events.mousePos(); + highlightIcon(Common::Point(pt.x - 4 + _bigPos.x, pt.y + _bigPos.y)); + } updateMap(false); } @@ -321,6 +326,34 @@ void Map::eraseTopLine() { screen.blitFrom(_topLine, Common::Point(0, 0)); } +/** + * Prints the name of the specified icon + */ +void Map::showPlaceName(int idx, bool highlighted) { + People &people = *_vm->_people; + Screen &screen = *_vm->_screen; + + Common::String name = _locationNames[idx]; + int width = screen.stringWidth(name); + + if (!_cursorIndex) { + saveIcon(people[AL]._imageFrame, _lDrawnPos); + + bool flipped = people[AL]._sequenceNumber == MAP_DOWNLEFT || people[AL]._sequenceNumber == MAP_LEFT + || people[AL]._sequenceNumber == MAP_UPLEFT; + screen._backBuffer1.transBlitFrom(people[AL]._imageFrame->_frame, _lDrawnPos, flipped); + } + + if (highlighted) { + int xp = (SHERLOCK_SCREEN_WIDTH - screen.stringWidth(name)) / 2; + screen.gPrint(Common::Point(xp + 2, 2), 0, name.c_str()); + screen.gPrint(Common::Point(xp + 1, 1), 0, name.c_str()); + screen.gPrint(Common::Point(xp, 0), 12, name.c_str()); + + screen.slamArea(xp, 0, screen.stringWidth(name) + 2, 15); + } +} + /** * Update all on-screen sprites to account for any scrolling of the map */ @@ -473,4 +506,45 @@ void Map::restoreIcon() { screen._backBuffer1.blitFrom(_iconSave, _savedPos); } +/** + * Handles highlighting map icons, showing their names + */ +void Map::highlightIcon(const Common::Point &pt) { + int oldPoint = _point; + + // Iterate through the icon list + bool done = false; + for (uint idx = 0; idx < _points.size(); ++idx) { + const MapEntry &entry = _points[idx]; + + // Check whether the mouse is over a given icon + if (entry.x != 0 && entry.y != 0) { + if (Common::Rect(entry.x - 8, entry.y - 8, entry.x + 9, entry.y + 9).contains(pt)) { + done = true; + + if (_point != idx && _vm->readFlags(idx)) { + // Changed to a new valid (visible) location + eraseTopLine(); + showPlaceName(idx, true); + _point = idx; + } + } + } + } + + if (!done) { + // No icon was highlighted + if (_point != -1) { + // No longer highlighting previously highlighted icon, so erase it + showPlaceName(_point, false); + eraseTopLine(); + } + + _point = -1; + } else if (oldPoint != -1 && oldPoint != _point) { + showPlaceName(oldPoint, false); + eraseTopLine(); + } +} + } // End of namespace Sherlock diff --git a/engines/sherlock/map.h b/engines/sherlock/map.h index 5b63fe768c..752137e0ba 100644 --- a/engines/sherlock/map.h +++ b/engines/sherlock/map.h @@ -76,6 +76,7 @@ private: void saveTopLine(); void eraseTopLine(); + void showPlaceName(int idx, bool highlighted); void updateMap(bool flushScreen); @@ -83,6 +84,8 @@ private: void saveIcon(ImageFrame *src, const Common::Point &pt); void restoreIcon(); + + void highlightIcon(const Common::Point &pt); public: Map(SherlockEngine *vm); -- cgit v1.2.3 From 02e604ce8c2b0a4f136a6d0815b55046c58ad92d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 22 Apr 2015 19:59:27 -0500 Subject: SHERLOCK: Fix display of Holmes' icon on overhead map --- engines/sherlock/map.cpp | 25 +++++++++++++++---------- engines/sherlock/map.h | 3 ++- engines/sherlock/objects.cpp | 7 ++++--- engines/sherlock/people.cpp | 13 +++++++------ engines/sherlock/sherlock.cpp | 1 - engines/sherlock/sherlock.h | 1 - 6 files changed, 28 insertions(+), 22 deletions(-) diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index b89b4b29fa..5173e0296e 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -26,14 +26,15 @@ namespace Sherlock { Map::Map(SherlockEngine *vm): _vm(vm), _topLine(SHERLOCK_SCREEN_WIDTH, 12) { + _active = false; _mapCursors = nullptr; _shapes = nullptr; _iconShapes = nullptr; _point = 0; _placesShown = false; - _charPoint = _oldCharPoint = -1; _cursorIndex = -1; _drawMap = false; + _overPos = Common::Point(13000, 12600); for (int idx = 0; idx < MAX_HOLMES_SEQUENCE; ++idx) Common::fill(&_sequences[idx][0], &_sequences[idx][MAX_FRAME], 0); @@ -103,9 +104,11 @@ void Map::loadData() { int Map::show() { Events &events = *_vm->_events; People &people = *_vm->_people; + Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; Common::Point lDrawn(-1, -1); bool changed = false, exitFlag = false; + _active = true; // Set font and custom cursor for the map int oldFont = screen.fontNumber(); @@ -204,7 +207,7 @@ int Map::show() { if ((events._released || events._rightReleased) && _point != -1) { if (people[AL]._walkCount == 0) { - _charPoint = _point; + scene._charPoint = _point; walkTheStreets(); _cursorIndex = 1; @@ -214,7 +217,7 @@ int Map::show() { // Check if a scene has beeen selected and we've finished "moving" to it if (people[AL]._walkCount == 0) { - if (_charPoint >= 1 && _charPoint < (int)_points.size()) + if (scene._charPoint >= 1 && scene._charPoint < (int)_points.size()) exitFlag = true; } @@ -238,7 +241,8 @@ int Map::show() { screen.setFont(oldFont); events.setCursor(ARROW); - return _charPoint; + _active = false; + return scene._charPoint; } /** @@ -350,7 +354,7 @@ void Map::showPlaceName(int idx, bool highlighted) { screen.gPrint(Common::Point(xp + 1, 1), 0, name.c_str()); screen.gPrint(Common::Point(xp, 0), 12, name.c_str()); - screen.slamArea(xp, 0, screen.stringWidth(name) + 2, 15); + screen.slamArea(xp, 0, width + 2, 15); } } @@ -408,21 +412,22 @@ void Map::updateMap(bool flushScreen) { */ void Map::walkTheStreets() { People &people = *_vm->_people; + Scene &scene = *_vm->_scene; bool reversePath = false; Common::Array tempPath; // Get indexes into the path lists for the start and destination scenes - int start = _points[_oldCharPoint]._translate; - int dest = _points[_charPoint]._translate; + int start = _points[scene._oldCharPoint]._translate; + int dest = _points[scene._charPoint]._translate; // Get pointer to start of path const int *ptr = &_paths[start][dest]; // Check for any intermediate points between the two locations - if (*ptr || _charPoint > 50 || _oldCharPoint > 50) { + if (*ptr || scene._charPoint > 50 || scene._oldCharPoint > 50) { people[AL]._sequenceNumber = -1; - if (_charPoint == 51 || _oldCharPoint == 51) { + if (scene._charPoint == 51 || scene._oldCharPoint == 51) { people.setWalking(); } else { // Check for moving the path backwards or forwards @@ -514,7 +519,7 @@ void Map::highlightIcon(const Common::Point &pt) { // Iterate through the icon list bool done = false; - for (uint idx = 0; idx < _points.size(); ++idx) { + for (int idx = 0; idx < (int)_points.size(); ++idx) { const MapEntry &entry = _points[idx]; // Check whether the mouse is over a given icon diff --git a/engines/sherlock/map.h b/engines/sherlock/map.h index 752137e0ba..da55a5e383 100644 --- a/engines/sherlock/map.h +++ b/engines/sherlock/map.h @@ -62,7 +62,6 @@ private: Common::Point _lDrawnPos; int _point; bool _placesShown; - int _charPoint, _oldCharPoint; int _cursorIndex; bool _drawMap; Surface _iconSave; @@ -86,6 +85,8 @@ private: void restoreIcon(); void highlightIcon(const Common::Point &pt); +public: + bool _active; public: Map(SherlockEngine *vm); diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index a1ead2c437..e5c6f847fb 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -81,6 +81,7 @@ void Sprite::setImageFrame() { * This adjusts the sprites position, as well as it's animation sequence: */ void Sprite::adjustSprite() { + Map &map = *_vm->_map; People &people = *_vm->_people; Scene &scene = *_vm->_scene; Talk &talk = *_vm->_talk; @@ -105,7 +106,7 @@ void Sprite::adjustSprite() { } } - if (_type == CHARACTER && !_vm->_onChessboard) { + if (_type == CHARACTER && !map._active) { if ((_position.y / 100) > LOWER_LIMIT) { _position.y = LOWER_LIMIT * 100; people.gotoStand(*this); @@ -120,12 +121,12 @@ void Sprite::adjustSprite() { _position.x = LEFT_LIMIT * 100; people.gotoStand(*this); } - } else if (!_vm->_onChessboard) { + } else if (!map._active) { _position.y = CLIP((int)_position.y, UPPER_LIMIT, LOWER_LIMIT); _position.x = CLIP((int)_position.x, LEFT_LIMIT, RIGHT_LIMIT); } - if (!_vm->_onChessboard || (_vm->_slowChess = !_vm->_slowChess)) + if (!map._active || (_vm->_slowChess = !_vm->_slowChess)) ++_frameNumber; if ((*_sequences)[_sequenceNumber][_frameNumber] == 0) { diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 0212be69b2..d247109a28 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -270,6 +270,7 @@ bool People::freeWalk() { * check for any obstacles in the path. */ void People::setWalking() { + Map &map = *_vm->_map; Scene &scene = *_vm->_scene; int oldDirection, oldFrame; Common::Point speed, delta; @@ -284,7 +285,7 @@ void People::setWalking() { oldFrame = _player._frameNumber; // Set speed to use horizontal and vertical movement - if (_vm->_onChessboard) { + if (map._active) { speed = Common::Point(MWALK_SPEED, MWALK_SPEED); } else { speed = Common::Point(XWALK_SPEED, YWALK_SPEED); @@ -321,10 +322,10 @@ void People::setWalking() { // Set the initial frame sequence for the left and right, as well // as settting the delta x depending on direction if (_walkDest.x < (_player._position.x / 100)) { - _player._sequenceNumber = _vm->_onChessboard ? MAP_LEFT : WALK_LEFT; + _player._sequenceNumber = map._active ? MAP_LEFT : WALK_LEFT; _player._delta.x = speed.x * -100; } else { - _player._sequenceNumber = _vm->_onChessboard ? MAP_RIGHT : WALK_RIGHT; + _player._sequenceNumber = map._active ? MAP_RIGHT : WALK_RIGHT; _player._delta.x = speed.x * 100; } @@ -348,7 +349,7 @@ void People::setWalking() { // See if the sequence needs to be changed for diagonal walking if (_player._delta.y > 150) { - if (!_vm->_onChessboard) { + if (!map._active) { switch (_player._sequenceNumber) { case WALK_LEFT: _player._sequenceNumber = WALK_DOWNLEFT; @@ -359,7 +360,7 @@ void People::setWalking() { } } } else if (_player._delta.y < -150) { - if (!_vm->_onChessboard) { + if (!map._active) { switch (_player._sequenceNumber) { case WALK_LEFT: _player._sequenceNumber = WALK_UPLEFT; @@ -447,7 +448,7 @@ void People::gotoStand(Sprite &sprite) { if (_oldWalkSequence != -1 || sprite._sequenceNumber == STOP_UP) sprite._frameNumber = 0; - if (_vm->_onChessboard) { + if (map._active) { sprite._sequenceNumber = 0; _data[AL]._position.x = (map[scene._charPoint].x - 6) * 100; _data[AL]._position.y = (map[scene._charPoint].x + 10) * 100; diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 518a7aa86b..d880257406 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -47,7 +47,6 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _ui = nullptr; _useEpilogue2 = false; _loadingSavedGame = false; - _onChessboard = false; _slowChess = false; _keyPadSpeed = 0; _loadGameSlot = -1; diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 916c9cd253..ce126c0dcc 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -106,7 +106,6 @@ public: bool _loadingSavedGame; int _oldCharPoint; // Old scene Common::Point _over; // Old map position - bool _onChessboard; bool _slowChess; int _keyPadSpeed; int _loadGameSlot; -- cgit v1.2.3 From e24ae07a90ccd0139112d5c086d49173834fa4a1 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 22 Apr 2015 21:11:26 -0500 Subject: SHERLOCK: Fix map path loading --- engines/sherlock/map.cpp | 60 +++++++++++++++++++++++++++++++++----------- engines/sherlock/map.h | 12 ++++++++- engines/sherlock/objects.cpp | 2 +- 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index 5173e0296e..0864997dff 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -25,6 +25,33 @@ namespace Sherlock { +/** + * Load the data for the paths between locations on the map + */ +void MapPaths::load(int numLocations, Common::SeekableReadStream &s) { + _numLocations = numLocations; + _paths.resize(_numLocations * _numLocations); + + for (int idx = 0; idx < (numLocations * numLocations); ++idx) { + Common::Array &path = _paths[idx]; + int v; + + do { + v = s.readByte(); + path.push_back(v); + } while (v && v < 254); + } +} + +/** + * Get the path between two locations on the map + */ +const byte *MapPaths::getPath(int srcLocation, int destLocation) { + return &_paths[srcLocation * _numLocations + destLocation][0]; +} + +/*----------------------------------------------------------------*/ + Map::Map(SherlockEngine *vm): _vm(vm), _topLine(SHERLOCK_SCREEN_WIDTH, 12) { _active = false; _mapCursors = nullptr; @@ -80,15 +107,10 @@ void Map::loadData() { // Load the path data Common::SeekableReadStream *pathStream = _vm->_res->load("chess.pth"); - _paths.resize(31); - for (uint idx = 0; idx < _paths.size(); ++idx) { - _paths[idx].resize(_paths.size()); + // Get routes between different locations on the map + _paths.load(31, *pathStream); - for (uint idx2 = 0; idx2 < _paths.size(); ++idx2) - _paths[idx][idx2] = pathStream->readSint16LE(); - } - - // Load in the path point information + // Load in the co-ordinates that the paths refer to _pathPoints.resize(208); for (uint idx = 0; idx < _pathPoints.size(); ++idx) { _pathPoints[idx].x = pathStream->readSint16LE(); @@ -207,9 +229,13 @@ int Map::show() { if ((events._released || events._rightReleased) && _point != -1) { if (people[AL]._walkCount == 0) { + people._walkDest = _points[_point] + Common::Point(4, 9); scene._charPoint = _point; + + // Start walking to selected location walkTheStreets(); + // Show wait cursor _cursorIndex = 1; events.setCursor((*_mapCursors)[_cursorIndex]); } @@ -373,7 +399,7 @@ void Map::updateMap(bool flushScreen) { if (++_cursorIndex > (1 + 8)) _cursorIndex = 1; - events.setCursor((*_mapCursors)[_cursorIndex]); + events.setCursor((*_mapCursors)[(_cursorIndex + 1) / 2]); } if (!_drawMap && !flushScreen) @@ -421,26 +447,30 @@ void Map::walkTheStreets() { int dest = _points[scene._charPoint]._translate; // Get pointer to start of path - const int *ptr = &_paths[start][dest]; + const byte *path = _paths.getPath(start, dest); + + // Add in destination position + people._walkTo.clear(); + people._walkTo.push(people._walkDest); // Check for any intermediate points between the two locations - if (*ptr || scene._charPoint > 50 || scene._oldCharPoint > 50) { + if (path[0] || scene._charPoint > 50 || scene._oldCharPoint > 50) { people[AL]._sequenceNumber = -1; if (scene._charPoint == 51 || scene._oldCharPoint == 51) { people.setWalking(); } else { // Check for moving the path backwards or forwards - if (*ptr == 255) { + if (path[0] == 255) { reversePath = true; SWAP(start, dest); - ptr = &_paths[start][dest]; + path = _paths.getPath(start, dest); } do { - int idx = *ptr++; + int idx = *path++; tempPath.push_back(_pathPoints[idx - 1] + Common::Point(4, 4)); - } while (*ptr != 254); + } while (*path != 254); // Load up the path to use people._walkTo.clear(); diff --git a/engines/sherlock/map.h b/engines/sherlock/map.h index da55a5e383..a91e7ae968 100644 --- a/engines/sherlock/map.h +++ b/engines/sherlock/map.h @@ -43,12 +43,22 @@ struct MapEntry : Common::Point { MapEntry(int x, int y, int translate) : Common::Point(x, y), _translate(translate) {} }; +class MapPaths { +private: + int _numLocations; + Common::Array< Common::Array > _paths; +public: + void load(int numLocations, Common::SeekableReadStream &s); + + const byte *getPath(int srcLocation, int destLocation); +}; + class Map { private: SherlockEngine *_vm; Common::Array _points; // Map locations for each scene Common::StringArray _locationNames; - Common::Array< Common::Array > _paths; + MapPaths _paths; Common::Array _pathPoints; Common::Point _savedPos; Common::Point _savedSize; diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index e5c6f847fb..262006b3b1 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -474,7 +474,7 @@ void Object::synchronize(Common::SeekableReadStream &s) { _defaultCommand = s.readByte(); _lookFlag = s.readUint16LE(); _pickupFlag = s.readUint16LE(); - _requiredFlag = s.readUint16LE(); + _requiredFlag = s.readSint16LE(); _noShapeSize.x = s.readUint16LE(); _noShapeSize.y = s.readUint16LE(); _status = s.readUint16LE(); -- cgit v1.2.3 From ecaa4c26c953524bdf34fa55cfdf6c55af129bc4 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 24 Apr 2015 00:53:19 -0500 Subject: SHERLOCK: Fix pathfinding for movement on map screen --- engines/sherlock/map.cpp | 20 +++++++++----------- engines/sherlock/people.cpp | 4 +++- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index 0864997dff..6e9982eb62 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -263,9 +263,8 @@ int Map::show() { freeSprites(); _overPos = people[AL]._position; - // Reset font and cursor + // Reset font screen.setFont(oldFont); - events.setCursor(ARROW); _active = false; return scene._charPoint; @@ -451,7 +450,7 @@ void Map::walkTheStreets() { // Add in destination position people._walkTo.clear(); - people._walkTo.push(people._walkDest); + Common::Point destPos = people._walkDest; // Check for any intermediate points between the two locations if (path[0] || scene._charPoint > 50 || scene._oldCharPoint > 50) { @@ -475,24 +474,23 @@ void Map::walkTheStreets() { // Load up the path to use people._walkTo.clear(); - if (!reversePath) { - for (int idx = 0; idx < (int)tempPath.size(); ++idx) + if (reversePath) { + for (int idx = (int)tempPath.size() - 1; idx >= 0; --idx) people._walkTo.push(tempPath[idx]); - - people._walkDest = tempPath.front(); } else { - for (int idx = 0; idx < ((int)tempPath.size() - 1); ++idx) + for (int idx = 0; idx < (int)tempPath.size(); ++idx) people._walkTo.push(tempPath[idx]); - people._walkDest = tempPath[tempPath.size() - 1]; } - people._walkDest.x += 12; - people._walkDest.y += 6; + people._walkDest = people._walkTo.pop() + Common::Point(12, 6); people.setWalking(); } } else { people[AL]._walkCount = 0; } + + // Store the final destination icon position + people._walkTo.push(destPos); } /** diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index d247109a28..e126757231 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -389,7 +389,9 @@ void People::setWalking() { // Set the delta x _player._delta.x = (delta.x * 100) / (delta.y / speed.y); if (_walkDest.x < (_player._position.x / 100)) - _player._delta.x = -_player._delta.x; + _player._delta.x = -_player._delta.x;; + + _player._walkCount = delta.y / speed.y; } } -- cgit v1.2.3 From a5edfcc3f5e59a8bb68b6bcbc8d7b6ce72ec633a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 24 Apr 2015 01:35:51 -0500 Subject: SHERLOCK: Fix restoring background as player icon moves on map --- engines/sherlock/map.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index 6e9982eb62..c3a5ba7b17 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -286,7 +286,7 @@ void Map::setupSprites() { _shapes = new ImageFile("mapicon.vgs"); _iconShapes = new ImageFile("overicon.vgs"); - + _iconSave.create((*_shapes)[4]._width, (*_shapes)[4]._height); Person &p = people[AL]; p._description = " "; p._type = CHARACTER; @@ -317,6 +317,7 @@ void Map::freeSprites() { delete _mapCursors; delete _shapes; delete _iconShapes; + _iconSave.free(); } /** @@ -523,9 +524,11 @@ void Map::saveIcon(ImageFrame *src, const Common::Point &pt) { return; } - _iconSave.create(size.x, size.y); + assert(size.x <= _iconSave.w && size.y <= _iconSave.h); _iconSave.blitFrom(screen._backBuffer1, Common::Point(0, 0), Common::Rect(pos.x, pos.y, pos.x + size.x, pos.y + size.y)); + _savedPos = pos; + _savedSize = size; } /** @@ -536,7 +539,7 @@ void Map::restoreIcon() { if (_savedPos.x >= 0 && _savedPos.y >= 0 && _savedPos.x <= SHERLOCK_SCREEN_WIDTH && _savedPos.y < SHERLOCK_SCREEN_HEIGHT) - screen._backBuffer1.blitFrom(_iconSave, _savedPos); + screen._backBuffer1.blitFrom(_iconSave, _savedPos, Common::Rect(0, 0, _savedSize.x, _savedSize.y)); } /** -- cgit v1.2.3 From e2b233e0bb62e14fcf454cda74966dd5df071654 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 24 Apr 2015 01:47:25 -0500 Subject: SHERLOCK: Fix button display in talk dialog --- engines/sherlock/talk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 6740e89efc..3eeb0f0af5 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -672,7 +672,7 @@ void Talk::drawInterface() { screen.makeButton(Common::Rect(99, CONTROLS_Y, 139, CONTROLS_Y + 10), 119 - screen.stringWidth("Exit") / 2, "Exit"); screen.makeButton(Common::Rect(140, CONTROLS_Y, 180, CONTROLS_Y + 10), - 159 - screen.stringWidth("Up"), "Up"); + 159 - screen.stringWidth("Up") / 2, "Up"); screen.makeButton(Common::Rect(181, CONTROLS_Y, 221, CONTROLS_Y + 10), 200 - screen.stringWidth("Down") / 2, "Down"); } else { -- cgit v1.2.3 From 572ad464901eedfd20ab5a35149e669f4bcac64a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 24 Apr 2015 02:17:59 -0500 Subject: SHERLOCK: Fix talk sequences being incorrectly started --- engines/sherlock/objects.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 262006b3b1..888c34fa04 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -195,17 +195,17 @@ void Sprite::checkSprite() { for (uint idx = 0; idx < scene._bgShapes.size() && !talk._talkToAbort; ++idx) { Object &obj = scene._bgShapes[idx]; + if (obj._aType <= PERSON || obj._type == INVALID || obj._type == HIDDEN) + continue; - if (obj._aType > PERSON && obj._type != INVALID && obj._type != HIDDEN) { - if (obj._type == NO_SHAPE) { - objBounds = Common::Rect(obj._position.x, obj._position.y, - obj._position.x + obj._noShapeSize.x, obj._position.y + obj._noShapeSize.y); - } else { - int xp = obj._position.x + obj._imageFrame->_offset.x; - int yp = obj._position.y + obj._imageFrame->_offset.y; - objBounds = Common::Rect(xp, yp, - xp + obj._imageFrame->_frame.w, yp + obj._imageFrame->_frame.h); - } + if (obj._type == NO_SHAPE) { + objBounds = Common::Rect(obj._position.x, obj._position.y, + obj._position.x + obj._noShapeSize.x, obj._position.y + obj._noShapeSize.y); + } else { + int xp = obj._position.x + obj._imageFrame->_offset.x; + int yp = obj._position.y + obj._imageFrame->_offset.y; + objBounds = Common::Rect(xp, yp, + xp + obj._imageFrame->_frame.w, yp + obj._imageFrame->_frame.h); } if (objBounds.contains(pt)) { -- cgit v1.2.3 From 79a3db42e1d9809facdd551f71744656073c1eb9 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 24 Apr 2015 02:29:18 -0500 Subject: SHERLOCK: Fix 'Press any key' interface messages --- engines/sherlock/user_interface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index a3631c577d..690eba2c84 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -72,8 +72,8 @@ const int SETUP_POINTS[12][4] = { const char COMMANDS[13] = "LMTPOCIUGJFS"; const char INVENTORY_COMMANDS[9] = { "ELUG-+,." }; -const char *const PRESS_KEY_FOR_MORE = "Press any _key for More."; -const char *const PRESS_KEY_TO_CONTINUE = "Press any _key to Continue."; +const char *const PRESS_KEY_FOR_MORE = "Press any Key for More."; +const char *const PRESS_KEY_TO_CONTINUE = "Press any Key to Continue."; const char *const MOPEN[] = { "This cannot be opened", "It is already open", "It is locked", "Wait for Watson", " ", "." -- cgit v1.2.3 From ecd50997ddaaf4c8ac648ecdb8bea1177f128610 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 24 Apr 2015 04:00:46 -0500 Subject: SHERLOCK: Fix Sherlock disappearing when walking to examine objects --- engines/sherlock/user_interface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 690eba2c84..903b1e6002 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -715,7 +715,7 @@ void UserInterface::examine() { scene.startCAnim(_cNum, canimSpeed); } else if (obj._lookPosition.y != 0) { // Need to walk to the object to be examined - people.walkToCoords(obj._lookPosition, obj._lookFacing); + people.walkToCoords(Common::Point(obj._lookPosition.x, obj._lookPosition.y * 100), obj._lookFacing); } if (!talk._talkToAbort) { -- cgit v1.2.3 From 51eb601f8393876a4ff847a5f4ff9068acd66fc8 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 24 Apr 2015 05:12:30 -0500 Subject: SHERLOCK: Fix loading/handling of sprite offsets --- engines/sherlock/objects.cpp | 4 ++-- engines/sherlock/resources.cpp | 4 ++-- engines/sherlock/scene.cpp | 53 +++++++++++++++++++----------------------- 3 files changed, 28 insertions(+), 33 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 888c34fa04..9e92b95532 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -691,8 +691,8 @@ bool Object::checkEndOfSequence() { if (seq == 99) { --_frameNumber; - screen._backBuffer1.transBlitFrom(_imageFrame->_frame, _position); - screen._backBuffer2.transBlitFrom(_imageFrame->_frame, _position); + screen._backBuffer1.transBlitFrom(*_imageFrame, _position); + screen._backBuffer2.transBlitFrom(*_imageFrame, _position); _type = INVALID; } else { setObjSequence(seq, false); diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index 262832c3c3..0d66646286 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -298,8 +298,8 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette) { frame._width = stream.readUint16LE() + 1; frame._height = stream.readUint16LE() + 1; frame._paletteBase = stream.readByte(); - frame._offset.x = stream.readUint16LE(); - frame._rleEncoded = ((frame._offset.x & 0xFF) == 1); + frame._rleEncoded = stream.readByte() == 1; + frame._offset.x = stream.readByte(); frame._offset.y = stream.readByte(); frame._rleEncoded = !skipPalette && frame._rleEncoded; diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 316b8739b1..e5d9fc611f 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -710,29 +710,27 @@ void Scene::updateBackground() { // Draw all active shapes which are behind the person for (uint idx = 0; idx < _bgShapes.size(); ++idx) { if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE && _bgShapes[idx]._misc == BEHIND) - surface.transBlitFrom(_bgShapes[idx]._imageFrame->_frame, - _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); + surface.transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); } // Draw all canimations which are behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if (_canimShapes[idx]._type == ACTIVE_BG_SHAPE && _canimShapes[idx]._misc == BEHIND) - surface.transBlitFrom(_canimShapes[idx]._imageFrame->_frame, + surface.transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, _canimShapes[idx]._flags & 2); } // Draw all active shapes which are normal and behind the person for (uint idx = 0; idx < _bgShapes.size(); ++idx) { if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE && _bgShapes[idx]._misc == NORMAL_BEHIND) - surface.transBlitFrom(_bgShapes[idx]._imageFrame->_frame, - _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); + surface.transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); } // Draw all canimations which are normal and behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if (_canimShapes[idx]._type == ACTIVE_BG_SHAPE && _canimShapes[idx]._misc == NORMAL_BEHIND) - surface.transBlitFrom(_canimShapes[idx]._imageFrame->_frame, - _canimShapes[idx]._position, _canimShapes[idx]._flags & 2); + surface.transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, + _canimShapes[idx]._flags & 2); } // Draw the player if he's active @@ -741,25 +739,23 @@ void Scene::updateBackground() { player._sequenceNumber == WALK_UPLEFT || player._sequenceNumber == STOP_UPLEFT || player._sequenceNumber == WALK_DOWNRIGHT || player._sequenceNumber == STOP_DOWNRIGHT; - surface.transBlitFrom(player._imageFrame->_frame, - Common::Point(player._position.x / 100, - player._position.y / 100 - player.frameHeight()), flipped); + surface.transBlitFrom(*player._imageFrame, Common::Point(player._position.x / 100, + player._position.y / 100 - player.frameHeight()), flipped); } // Draw all static and active shapes that are NORMAL and are in front of the player for (uint idx = 0; idx < _bgShapes.size(); ++idx) { if ((_bgShapes[idx]._type == ACTIVE_BG_SHAPE || _bgShapes[idx]._type == STATIC_BG_SHAPE) && _bgShapes[idx]._misc == NORMAL_FORWARD) - surface.transBlitFrom(_bgShapes[idx]._imageFrame->_frame, - _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); + surface.transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); } // Draw all static and active canimations that are NORMAL and are in front of the player for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if ((_canimShapes[idx]._type == ACTIVE_BG_SHAPE || _canimShapes[idx]._type == STATIC_BG_SHAPE) && _canimShapes[idx]._misc == NORMAL_FORWARD) - surface.transBlitFrom(_canimShapes[idx]._imageFrame->_frame, - _canimShapes[idx]._position, _canimShapes[idx]._flags & 2); + surface.transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, + _canimShapes[idx]._flags & 2); } // Draw all static and active shapes that are FORWARD @@ -770,16 +766,15 @@ void Scene::updateBackground() { if ((_bgShapes[idx]._type == ACTIVE_BG_SHAPE || _bgShapes[idx]._type == STATIC_BG_SHAPE) && _bgShapes[idx]._misc == FORWARD) - surface.transBlitFrom(_bgShapes[idx]._imageFrame->_frame, - _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); + surface.transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); } // Draw all static and active canimations that are forward for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if ((_canimShapes[idx]._type == ACTIVE_BG_SHAPE || _canimShapes[idx]._type == STATIC_BG_SHAPE) && _canimShapes[idx]._misc == FORWARD) - surface.transBlitFrom(_canimShapes[idx]._imageFrame->_frame, - _canimShapes[idx]._position, _canimShapes[idx]._flags & 2); + surface.transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, + _canimShapes[idx]._flags & 2); } } @@ -1196,14 +1191,14 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == BEHIND) - screen._backBuffer1.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } // Draw all canimations which are behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == BEHIND) { - screen._backBuffer1.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } } @@ -1211,14 +1206,14 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == NORMAL_BEHIND) - screen._backBuffer1.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } // Draw all canimations which are NORMAL and behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == NORMAL_BEHIND) { - screen._backBuffer1.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } } @@ -1231,7 +1226,7 @@ void Scene::doBgAnim() { bool flipped = people[AL]._sequenceNumber == WALK_LEFT || people[AL]._sequenceNumber == STOP_LEFT || people[AL]._sequenceNumber == WALK_UPLEFT || people[AL]._sequenceNumber == STOP_UPLEFT || people[AL]._sequenceNumber == WALK_DOWNRIGHT || people[AL]._sequenceNumber == STOP_DOWNRIGHT; - screen._backBuffer1.transBlitFrom(people[AL]._imageFrame->_frame, + screen._backBuffer1.transBlitFrom(*people[AL]._imageFrame, Common::Point(tempX, people[AL]._position.y / 100 - people[AL]._imageFrame->_frame.h), flipped); } @@ -1239,14 +1234,14 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == NORMAL_FORWARD) - screen._backBuffer1.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } // Draw all static and active canimations that are NORMAL and are in front of the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == NORMAL_BEHIND) { - screen._backBuffer1.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } } @@ -1254,19 +1249,19 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == FORWARD) - screen._backBuffer1.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } // Draw any active portrait if (people._portraitLoaded && people._portrait._type == ACTIVE_BG_SHAPE) - screen._backBuffer1.transBlitFrom(people._portrait._imageFrame->_frame, + screen._backBuffer1.transBlitFrom(*people._portrait._imageFrame, people._portrait._position, people._portrait._flags & 2); // Draw all static and active canimations that are in front of the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == FORWARD) { - screen._backBuffer1.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } } @@ -1274,7 +1269,7 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if (o._type == NO_SHAPE && (o._flags & 1) == 0) - screen._backBuffer1.transBlitFrom(o._imageFrame->_frame, o._position, o._flags & 2); + screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } // Bring the newly built picture to the screen -- cgit v1.2.3 From 5e1588e5cc9030c611609df23941609c68df4b65 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 24 Apr 2015 17:25:37 -0500 Subject: SHERLOCK: Fix display of look description dialogs --- engines/sherlock/talk.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 3eeb0f0af5..0ac1bbd6aa 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -678,7 +678,7 @@ void Talk::drawInterface() { } else { int strWidth = screen.stringWidth(PRESS_KEY_TO_CONTINUE); screen.makeButton(Common::Rect(46, CONTROLS_Y, 273, CONTROLS_Y + 10), - 160 - strWidth, PRESS_KEY_TO_CONTINUE); + 160 - strWidth / 2, PRESS_KEY_TO_CONTINUE); screen.gPrint(Common::Point(160 - strWidth / 2, CONTROLS_Y), COMMAND_FOREGROUND, "P"); } } @@ -913,12 +913,14 @@ void Talk::pushSequence(int speaker) { } else { seqEntry._objNum = people.findSpeaker(speaker); - Object &obj = scene._bgShapes[seqEntry._objNum]; - for (uint idx = 0; idx < MAX_TALK_SEQUENCES; ++idx) - seqEntry._sequences.push_back(obj._sequences[idx]); + if (seqEntry._objNum != -1) { + Object &obj = scene._bgShapes[seqEntry._objNum]; + for (uint idx = 0; idx < MAX_TALK_SEQUENCES; ++idx) + seqEntry._sequences.push_back(obj._sequences[idx]); - seqEntry._frameNumber = obj._frameNumber; - seqEntry._seqTo = obj._seqTo; + seqEntry._frameNumber = obj._frameNumber; + seqEntry._seqTo = obj._seqTo; + } } _sequenceStack.push(seqEntry); @@ -1549,13 +1551,14 @@ void Talk::doScript(const Common::String &script) { screen.print(Common::Point(16, yp), INV_FOREGROUND, lineStr.c_str()); } else { screen.gPrint(Common::Point(16, yp - 1), INV_FOREGROUND, lineStr.c_str()); + openTalkWindow = true; } } else { if (ui._windowOpen) { screen.print(Common::Point(16, yp), COMMAND_FOREGROUND, lineStr.c_str()); - } - else { + } else { screen.gPrint(Common::Point(16, yp - 1), COMMAND_FOREGROUND, lineStr.c_str()); + openTalkWindow = true; } } -- cgit v1.2.3 From 6eb51c3d50e5134c4054f9652624fe61d772b004 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 24 Apr 2015 17:27:23 -0500 Subject: SHERLOCK: Formatting fixes --- engines/sherlock/objects.cpp | 4 ++-- engines/sherlock/talk.cpp | 6 ++---- engines/sherlock/user_interface.cpp | 3 +-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 9e92b95532..78b6cda2d3 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -309,10 +309,10 @@ void Sprite::checkSprite() { if (_delta.x > 0) // Go to right side walkPos.x = objBounds.right + CLEAR_DIST_X; - else if (_delta.x < 0) + else if (_delta.x < 0) { // Go to left side walkPos.x = objBounds.left - CLEAR_DIST_X; - else { + } else { // Going straight up or down. So choose best side if (spritePt.x >= (objBounds.left + objBounds.width() / 2)) walkPos.x = objBounds.right + CLEAR_DIST_X; diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 0ac1bbd6aa..9be2b035d4 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1041,8 +1041,7 @@ void Talk::doScript(const Common::String &script) { pullSequence(); pushSequence(_speaker); setSequence(_speaker); - } - else { + } else { setSequence(_speaker); } @@ -1071,8 +1070,7 @@ void Talk::doScript(const Common::String &script) { // Remove portrait? if (str[0] == REMOVE_PORTRAIT) { _speaker = 255; - } - else { + } else { // Nope, so set the first speaker people.setTalking(_speaker); } diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 903b1e6002..a2a356127c 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1468,8 +1468,7 @@ void UserInterface::doLookControl() { _menuMode = STD_MODE; events.clearEvents(); } - } - else { + } else { // Looking at an inventory object // Backup the user interface Surface tempSurface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y1); -- cgit v1.2.3 From 930600c85740012db40a11eb06b02b0c78356529 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 24 Apr 2015 17:47:58 -0500 Subject: SHERLOCK: Implement saving scene status when saving game or leaving scene --- engines/sherlock/scene.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index e5d9fc611f..3ecc7be422 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -451,7 +451,7 @@ bool Scene::loadScene(const Common::String &filename) { * opening or moving them */ void Scene::checkSceneStatus() { - if (_sceneStats[_currentScene][65]) { + if (_sceneStats[_currentScene][64]) { for (uint idx = 0; idx < 64; ++idx) { int val = _sceneStats[_currentScene][idx]; @@ -475,6 +475,23 @@ void Scene::checkSceneStatus() { } } +/** + * Restores objects to the correct status. This ensures that things like being opened or moved + * will remain the same on future visits to the scene + */ +void Scene::saveSceneStatus() { + // Flag any objects for the scene that have been altered + int count = MIN((int)_bgShapes.size(), 64); + for (int idx = 0; idx < count; ++idx) { + Object &obj = _bgShapes[idx]; + _sceneStats[_currentScene][idx] = obj._type == HIDDEN || obj._type == REMOVE + || obj._type == HIDE_SHAPE || obj._type == INVALID; + } + + // Flag scene as having been visited + _sceneStats[_currentScene][64] = true; +} + /** * Check the scene's objects against the game flags. If false is passed, * it means the scene has just been loaded. A value of true means that the scene @@ -1364,10 +1381,6 @@ void Scene::doBgAnim() { } } -void Scene::saveSceneStatus() { - // TODO -} - /** * Attempts to find a background shape within the passed bounds. If found, * it will return the shape number, or -1 on failure. @@ -1453,6 +1466,9 @@ int Scene::closestZone(const Common::Point &pt) { * Synchronize the data for a savegame */ void Scene::synchronize(Common::Serializer &s) { + if (s.isSaving()) + saveSceneStatus(); + s.syncAsSint16LE(_bigPos.x); s.syncAsSint16LE(_bigPos.y); s.syncAsSint16LE(_overPos.x); -- cgit v1.2.3 From 3cf1afb459e29747461e21ba7db971a9c72fc9ff Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 24 Apr 2015 20:26:33 -0500 Subject: SHERLOCK: Fix minor gfx glitch when sliding up closing dialogs --- engines/sherlock/user_interface.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index a2a356127c..12af04d608 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1304,7 +1304,7 @@ void UserInterface::doInvControl() { } if (events._released || _keyboardInput) { - if ((!found && events._released) && _key == 'E') { + if ((found == 0 && events._released) || _key == 'E') { inv.freeInv(); _infoFlag = true; clearInfo(); @@ -2454,6 +2454,11 @@ void UserInterface::banishWindow(bool slideUp) { SHERLOCK_SCREEN_HEIGHT); events.delay(10); } + + // Show entire final area + screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(0, CONTROLS_Y1), + Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + screen.slamRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); } _infoFlag = false; -- cgit v1.2.3 From 55404f01d60fb4bb454ceb8e9289debbadda8470 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 24 Apr 2015 20:59:30 -0500 Subject: SHERLOCK: Fix talk dialog buttons --- engines/sherlock/talk.cpp | 8 ++++---- engines/sherlock/user_interface.cpp | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 9be2b035d4..2ad70dabed 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -698,13 +698,13 @@ bool Talk::displayTalk(bool slamIt) { } if (_talkIndex) { - for (uint idx = 0; idx < _statements.size(); ++idx) { + for (int idx = 0; idx < _talkIndex && !_moreTalkUp; ++idx) { if (_statements[idx]._talkMap != -1) _moreTalkUp = true; } } - // Display the up arrow if the first option is scrolled off-screen + // Display the up arrow and enable Up button if the first option is scrolled off-screen if (_moreTalkUp) { if (slamIt) { screen.print(Common::Point(5, CONTROLS_Y + 13), INV_FOREGROUND, "~"); @@ -747,7 +747,7 @@ bool Talk::displayTalk(bool slamIt) { } } - // Display the down arrow if there are more statements available + // Display the down arrow and enable down button if there are more statements available down off-screen if (lineY == -1 || lineY == SHERLOCK_SCREEN_HEIGHT) { _moreTalkDown = true; @@ -763,7 +763,7 @@ bool Talk::displayTalk(bool slamIt) { screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, true, "Down"); screen.vgaBar(Common::Rect(5, 189, 16, 199), INV_BACKGROUND); } else { - screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_FOREGROUND, false, "Down"); + screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, false, "Down"); screen._backBuffer1.fillRect(Common::Rect(5, 189, 16, 199), INV_BACKGROUND); } } diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 12af04d608..176b1bc42b 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1791,14 +1791,14 @@ void UserInterface::doTalkControl() { } if (events._released || _keyboardInput) { - if (_endKeyActive && ((mousePos.x > 99 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 10) - && talk._moreTalkUp && events._released) || _key == 'E')) { + if (((Common::Rect(99, CONTROLS_Y, 138, CONTROLS_Y + 10).contains(mousePos) && events._released) + || _key == 'E') && _endKeyActive) { talk.freeTalkVars(); talk.pullSequence(); banishWindow(); _windowBounds.top = CONTROLS_Y1; - } else if ((mousePos.x > 140 && mousePos.x < 179 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 10) - && talk._moreTalkUp && events._released) || (talk._moreTalkUp && _key == 'U')) { + } else if (((Common::Rect(140, CONTROLS_Y, 179, CONTROLS_Y + 10).contains(mousePos) && events._released) + || _key == 'U') && talk._moreTalkUp) { while (talk._statements[--talk._talkIndex]._talkMap == -1) ; screen._backBuffer1.fillRect(Common::Rect(5, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, @@ -1806,8 +1806,8 @@ void UserInterface::doTalkControl() { talk.displayTalk(false); screen.slamRect(Common::Rect(5, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH - 5, SHERLOCK_SCREEN_HEIGHT - 2)); - } else if ((mousePos.x > 181 && mousePos.x < 220 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 10) - && talk._moreTalkDown && events._released) || (talk._moreTalkDown && _key == 'D')) { + } else if (((Common::Rect(181, CONTROLS_Y, 220, CONTROLS_Y + 10).contains(mousePos) && events._released) + || _key == 'D') && talk._moreTalkDown) { do { ++talk._talkIndex; } while (talk._talkIndex < (int)talk._statements.size() && talk._statements[talk._talkIndex]._talkMap == -1); -- cgit v1.2.3 From 8fa2d48f1f00b4be5e04c305db2a5340e4480d89 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 24 Apr 2015 21:12:05 -0500 Subject: SHERLOCK: Fix crash when entering backstage area --- engines/sherlock/journal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 18edec8c73..bb1fc9a883 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -286,7 +286,7 @@ int Journal::loadJournalFile(bool alreadyLoaded) { else if (talk._talkTo == 2) journalString += "The Inspector"; else - journalString += inv._names[talk._talkTo]; + journalString += NAMES[talk._talkTo]; const char *strP = replyP; char v; -- cgit v1.2.3 From c92b3b5c71666797eb6d26008ebbfd88d69573c3 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 24 Apr 2015 22:12:15 -0500 Subject: SHERLOCK: Fix paging in the journal --- engines/sherlock/journal.cpp | 66 +++++++++++++++++++++++--------------------- engines/sherlock/journal.h | 4 +-- 2 files changed, 37 insertions(+), 33 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index bb1fc9a883..e3d4e1b7a3 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -136,7 +136,6 @@ void Journal::loadJournalLocations() { */ int Journal::loadJournalFile(bool alreadyLoaded) { Inventory &inv = *_vm->_inventory; - People &people = *_vm->_people; Screen &screen = *_vm->_screen; Talk &talk = *_vm->_talk; JournalEntry &journalEntry = _journal[_index]; @@ -156,7 +155,7 @@ int Journal::loadJournalFile(bool alreadyLoaded) { // Find the person being talked to talk._talkTo = -1; for (int idx = 0; idx < MAX_PEOPLE; ++idx) { - Common::String portrait = people[idx]._portrait; + Common::String portrait = PORTRAITS[idx]; Common::String numStr(portrait.c_str(), portrait.c_str() + 4); if (locStr == numStr) { @@ -243,7 +242,7 @@ int Journal::loadJournalFile(bool alreadyLoaded) { const char *replyP = statement._reply.c_str(); while (*replyP) { - char c = *replyP++; + byte c = *replyP++; // Is it a control character? if (c < 128) { @@ -288,7 +287,7 @@ int Journal::loadJournalFile(bool alreadyLoaded) { else journalString += NAMES[talk._talkTo]; - const char *strP = replyP; + const char *strP = replyP + 1; char v; do { v = *strP++; @@ -354,6 +353,7 @@ int Journal::loadJournalFile(bool alreadyLoaded) { case 136: // Pause without control case 157: // Walk to canimation // These commands don't have any param + ++replyP; break; case 134: // Change sequence @@ -450,7 +450,10 @@ int Journal::loadJournalFile(bool alreadyLoaded) { return _lines.size(); } -void Journal::drawInterface() { +/** + * Draw the journal frame + */ +void Journal::drawJournal() { Resources &res = *_vm->_res; Screen &screen = *_vm->_screen; byte palette[PALETTE_SIZE]; @@ -471,33 +474,42 @@ void Journal::drawInterface() { screen.gPrint(Common::Point(110, 17), INV_FOREGROUND, "Watson's Journal"); // Draw the buttons - screen.makeButton(Common::Rect(JOURNAL_POINTS[0][0], JOURNAL_BUTTONS_Y, - JOURNAL_POINTS[0][1], JOURNAL_BUTTONS_Y + 10), + screen.makeButton(Common::Rect(JOURNAL_POINTS[0][0], JOURNAL_BUTTONS_Y, + JOURNAL_POINTS[0][1], JOURNAL_BUTTONS_Y + 10), JOURNAL_POINTS[0][2] - screen.stringWidth("Exit") / 2, "Exit"); - screen.makeButton(Common::Rect(JOURNAL_POINTS[1][0], JOURNAL_BUTTONS_Y, - JOURNAL_POINTS[1][1], JOURNAL_BUTTONS_Y + 10), + screen.makeButton(Common::Rect(JOURNAL_POINTS[1][0], JOURNAL_BUTTONS_Y, + JOURNAL_POINTS[1][1], JOURNAL_BUTTONS_Y + 10), JOURNAL_POINTS[1][2] - screen.stringWidth("Back 10") / 2, "Back 10"); - screen.makeButton(Common::Rect(JOURNAL_POINTS[2][0], JOURNAL_BUTTONS_Y, - JOURNAL_POINTS[2][1], JOURNAL_BUTTONS_Y + 10), + screen.makeButton(Common::Rect(JOURNAL_POINTS[2][0], JOURNAL_BUTTONS_Y, + JOURNAL_POINTS[2][1], JOURNAL_BUTTONS_Y + 10), JOURNAL_POINTS[2][2] - screen.stringWidth("Up") / 2, "Up"); - screen.makeButton(Common::Rect(JOURNAL_POINTS[3][0], JOURNAL_BUTTONS_Y, - JOURNAL_POINTS[3][1], JOURNAL_BUTTONS_Y + 10), + screen.makeButton(Common::Rect(JOURNAL_POINTS[3][0], JOURNAL_BUTTONS_Y, + JOURNAL_POINTS[3][1], JOURNAL_BUTTONS_Y + 10), JOURNAL_POINTS[3][2] - screen.stringWidth("Down") / 2, "Down"); - screen.makeButton(Common::Rect(JOURNAL_POINTS[4][0], JOURNAL_BUTTONS_Y, + screen.makeButton(Common::Rect(JOURNAL_POINTS[4][0], JOURNAL_BUTTONS_Y, JOURNAL_POINTS[4][1], JOURNAL_BUTTONS_Y + 10), JOURNAL_POINTS[4][2] - screen.stringWidth("Ahead 10") / 2, "Ahead 10"); - screen.makeButton(Common::Rect(JOURNAL_POINTS[5][0], JOURNAL_BUTTONS_Y + 11, + screen.makeButton(Common::Rect(JOURNAL_POINTS[5][0], JOURNAL_BUTTONS_Y + 11, JOURNAL_POINTS[5][1], JOURNAL_BUTTONS_Y + 21), JOURNAL_POINTS[5][2] - screen.stringWidth("Search") / 2, "Search"); - screen.makeButton(Common::Rect(JOURNAL_POINTS[6][0], JOURNAL_BUTTONS_Y + 11, + screen.makeButton(Common::Rect(JOURNAL_POINTS[6][0], JOURNAL_BUTTONS_Y + 11, JOURNAL_POINTS[6][1], JOURNAL_BUTTONS_Y + 21), JOURNAL_POINTS[6][2] - screen.stringWidth("First Page") / 2, "First Page"); - screen.makeButton(Common::Rect(JOURNAL_POINTS[7][0], JOURNAL_BUTTONS_Y + 11, + screen.makeButton(Common::Rect(JOURNAL_POINTS[7][0], JOURNAL_BUTTONS_Y + 11, JOURNAL_POINTS[7][1], JOURNAL_BUTTONS_Y + 21), JOURNAL_POINTS[7][2] - screen.stringWidth("Last Page") / 2, "Last Page"); - screen.makeButton(Common::Rect(JOURNAL_POINTS[8][0], JOURNAL_BUTTONS_Y + 11, + screen.makeButton(Common::Rect(JOURNAL_POINTS[8][0], JOURNAL_BUTTONS_Y + 11, JOURNAL_POINTS[8][1], JOURNAL_BUTTONS_Y + 21), JOURNAL_POINTS[8][2] - screen.stringWidth("Print Text") / 2, "Print Text"); +} + +/** + * Display the journal + */ +void Journal::drawInterface() { + Screen &screen = *_vm->_screen; + + drawJournal(); if (_journal.size() == 0) { _up = _down = 0; @@ -578,7 +590,7 @@ bool Journal::doJournal(int direction, int howFar) { if (endJournal) { // If moving forward or backwards, clear the page before printing if (direction) - clearPage(); + drawJournal(); screen.gPrint(Common::Point(235, 21), PEN_COLOR, "Page %d", _page); return false; @@ -701,7 +713,7 @@ bool Journal::doJournal(int direction, int howFar) { if (direction) { events.setCursor(ARROW); - clearPage(); + drawJournal(); } screen.gPrint(Common::Point(235, 21), PEN_COLOR, "Page %d", _page); @@ -785,14 +797,6 @@ bool Journal::doJournal(int direction, int howFar) { return direction >= 3 && searchSuccessful; } -/** - * Clears the journal page - */ -void Journal::clearPage() { - // Clear the journal page by redrawing it from scratch - drawInterface(); -} - /** * Handle events whilst the journal is being displayed */ @@ -962,7 +966,7 @@ bool Journal::handleEvents(int key) { _sub = savedSub; _page = savedPage; - clearPage(); + drawJournal(); doJournal(0, 0); notFound = true; } else { @@ -984,7 +988,7 @@ bool Journal::handleEvents(int key) { _up = _down = false; _page = 1; - clearPage(); + drawJournal(); doJournal(0, 0); doArrows(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); @@ -1168,7 +1172,7 @@ int Journal::getFindName(bool printError) { } // Redisplay the journal screen - clearPage(); + drawJournal(); doJournal(0, 0); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h index 9db4b28665..a67e0e51e2 100644 --- a/engines/sherlock/journal.h +++ b/engines/sherlock/journal.h @@ -67,9 +67,9 @@ private: bool doJournal(int direction, int howFar); - void clearPage(); - int getFindName(bool printError); + + void drawJournal(); public: Journal(SherlockEngine *vm); -- cgit v1.2.3 From baeca76b028ff846ce14bad4575984324fd4c999 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 25 Apr 2015 03:05:51 -0500 Subject: SHERLOCK: Fix crash displaying journal contents for Lestrade --- engines/sherlock/journal.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index e3d4e1b7a3..1891419acf 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -248,6 +248,7 @@ int Journal::loadJournalFile(bool alreadyLoaded) { if (c < 128) { // Nope. Set flag for allowing control coes to insert spaces ctrlSpace = true; + assert(c >= ' '); // Check for embedded comments if (c == '{' || c == '}') { @@ -307,7 +308,7 @@ int Journal::loadJournalFile(bool alreadyLoaded) { journalString += c; do { journalString += *replyP++; - } while (*replyP && *replyP < 128 && *replyP != '{' && *replyP != '}'); + } while (*replyP && (byte)*replyP < 128 && *replyP != '{' && *replyP != '}'); commentJustPrinted = false; } @@ -323,16 +324,16 @@ int Journal::loadJournalFile(bool alreadyLoaded) { } startOfReply = false; - c = *replyP++; + c = *replyP++ - 1; - if ((c - 1) == 0) + if (c == 0) journalString += "Holmes"; - else if ((c - 1) == 1) + else if (c == 1) journalString += "I"; - else if ((c - 1) == 2) + else if (c == 2) journalString += "the Inspector"; else - journalString += inv._names[c - 1]; + journalString += NAMES[c]; const char *strP = replyP; char v; @@ -352,7 +353,7 @@ int Journal::loadJournalFile(bool alreadyLoaded) { case 131: // Pause with control case 136: // Pause without control case 157: // Walk to canimation - // These commands don't have any param + // These commands have a single parameter ++replyP; break; @@ -821,7 +822,7 @@ bool Journal::handleEvents(int key) { } else { color = COMMAND_FOREGROUND; } - screen.buttonPrint(Common::Point(JOURNAL_POINTS[1][2], JOURNAL_BUTTONS_Y), color, true, "Exit"); + screen.buttonPrint(Common::Point(JOURNAL_POINTS[0][2], JOURNAL_BUTTONS_Y), color, true, "Exit"); // Back 10 button if (pt.x > JOURNAL_POINTS[1][0] && pt.x < JOURNAL_POINTS[1][1] && pt.y >= JOURNAL_BUTTONS_Y && -- cgit v1.2.3 From c6286ec4bd88a4c8a5dc0b5934f8c3241ab2d237 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 25 Apr 2015 03:14:35 -0500 Subject: SHERLOCK: Journal paging fix --- engines/sherlock/journal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 1891419acf..91148a2694 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -679,7 +679,7 @@ bool Journal::doJournal(int direction, int howFar) { if (++_sub == maxLines) { // Reached end of page do { - if (++_index == (int)_lines.size()) { + if (++_index == _count) { _index = savedIndex; _sub = savedSub; maxLines = loadJournalFile(false); -- cgit v1.2.3 From eb91c01cf160984f52edf5ba1da3f5db1e2a6519 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 25 Apr 2015 03:19:08 -0500 Subject: SHERLOCK: Fix paging to end of journal --- engines/sherlock/journal.cpp | 4 +--- engines/sherlock/journal.h | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 91148a2694..46114cd746 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -51,7 +51,6 @@ const int SEARCH_POINTS[3][3] = { Journal::Journal(SherlockEngine *vm): _vm(vm) { // Initialize fields - _count = 0; _maxPage = 0; _index = 0; _sub = 0; @@ -679,7 +678,7 @@ bool Journal::doJournal(int direction, int howFar) { if (++_sub == maxLines) { // Reached end of page do { - if (++_index == _count) { + if (++_index == (int)_journal.size()) { _index = savedIndex; _sub = savedSub; maxLines = loadJournalFile(false); @@ -1192,7 +1191,6 @@ void Journal::resetPosition() { * Synchronize the data for a savegame */ void Journal::synchronize(Common::Serializer &s) { - s.syncAsSint16LE(_count); s.syncAsSint16LE(_index); s.syncAsSint16LE(_sub); s.syncAsSint16LE(_page); diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h index a67e0e51e2..2ef0f94492 100644 --- a/engines/sherlock/journal.h +++ b/engines/sherlock/journal.h @@ -50,7 +50,6 @@ private: Common::StringArray _directory; Common::StringArray _locations; Common::StringArray _lines; - int _count; int _maxPage; int _index; int _sub; -- cgit v1.2.3 From 2379824e32fd0cb49e3f2b6c997cb6070f0b0393 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 25 Apr 2015 04:42:15 -0500 Subject: SHERLOCK: Fix saving and display of inventory items --- engines/sherlock/inventory.cpp | 19 +++++++++++++++++-- engines/sherlock/inventory.h | 4 +++- engines/sherlock/journal.cpp | 3 +-- engines/sherlock/saveload.cpp | 2 ++ 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index 3ba6f9d2bd..808429f643 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -31,6 +31,17 @@ InventoryItem::InventoryItem(int requiredFlag, const Common::String &name, _examine(examine), _lookFlag(0) { } +/** + * Synchronize the data for an inventory item + */ +void InventoryItem::synchronize(Common::Serializer &s) { + s.syncAsSint16LE(_requiredFlag); + s.syncAsSint16LE(_lookFlag); + s.syncString(_name); + s.syncString(_description); + s.syncString(_examine); +} + /*----------------------------------------------------------------*/ Inventory::Inventory(SherlockEngine *vm) : Common::Array(), _vm(vm) { @@ -47,6 +58,9 @@ Inventory::~Inventory() { freeGraphics(); } +/** + * Free inventory data + */ void Inventory::freeInv() { freeGraphics(); @@ -117,7 +131,7 @@ void Inventory::loadGraphics() { * and returns the numer that matches the passed name */ int Inventory::findInv(const Common::String &name) { - for (int idx = 0; idx < (int)size(); ++idx) { + for (int idx = 0; idx < (int)_names.size(); ++idx) { if (scumm_stricmp(name.c_str(), _names[idx].c_str()) == 0) return idx; } @@ -502,7 +516,8 @@ void Inventory::synchronize(Common::Serializer &s) { } for (uint idx = 0; idx < size(); ++idx) { - // TODO + (*this)[idx].synchronize(s); + } } diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index bccdc9336e..0dafdddde9 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -57,16 +57,18 @@ struct InventoryItem { InventoryItem() : _requiredFlag(0), _lookFlag(0) {} InventoryItem(int requiredFlag, const Common::String &name, const Common::String &description, const Common::String &examine); + + void synchronize(Common::Serializer &s); }; class Inventory : public Common::Array { private: SherlockEngine *_vm; + Common::StringArray _names; void copyToInventory(Object &obj); public: ImageFile *_invShapes[MAX_VISIBLE_INVENTORY]; - Common::StringArray _names; bool _invGraphicsLoaded; InvMode _invMode; int _invIndex; diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 46114cd746..ffda25a533 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -134,7 +134,6 @@ void Journal::loadJournalLocations() { * word wraps the result to prepare it for being displayed */ int Journal::loadJournalFile(bool alreadyLoaded) { - Inventory &inv = *_vm->_inventory; Screen &screen = *_vm->_screen; Talk &talk = *_vm->_talk; JournalEntry &journalEntry = _journal[_index]; @@ -224,7 +223,7 @@ int Journal::loadJournalFile(bool alreadyLoaded) { journalString += "the Inspector"; break; default: - journalString += inv._names[talk._talkTo]; + journalString += NAMES[talk._talkTo]; break; } journalString += ", \""; diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index 7610c42d8c..a694e21b28 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -366,6 +366,7 @@ Common::String SaveManager::generateSaveName(int slot) { * Synchronize the data for a savegame */ void SaveManager::synchronize(Common::Serializer &s) { + Inventory &inv = *_vm->_inventory; Journal &journal = *_vm->_journal; People &people = *_vm->_people; Scene &scene = *_vm->_scene; @@ -374,6 +375,7 @@ void SaveManager::synchronize(Common::Serializer &s) { int oldFont = screen.fontNumber(); + inv.synchronize(s); journal.synchronize(s); people.synchronize(s); scene.synchronize(s); -- cgit v1.2.3 From b8e12bbd88dba43cd397aca151eddb47d2ce761a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 25 Apr 2015 05:11:07 -0500 Subject: SHERLOCK: Fix setting scene flags when leaving a scene --- engines/sherlock/scene.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 3ecc7be422..3f551ef5ba 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -129,6 +129,9 @@ void Scene::selectScene() { _oldKey = _help = _oldHelp = 0; _oldTemp = _temp = 0; + // Free any previous scene + freeScene(); + // Load the scene Common::String sceneFile = Common::String::format("res%02d", _goToScene); _rrmName = Common::String::format("res%02d.rrm", _goToScene); @@ -201,7 +204,6 @@ bool Scene::loadScene(const Common::String &filename) { UserInterface &ui = *_vm->_ui; bool flag; - freeScene(); _walkedInScene = false; _ongoingCans = 0; @@ -453,12 +455,12 @@ bool Scene::loadScene(const Common::String &filename) { void Scene::checkSceneStatus() { if (_sceneStats[_currentScene][64]) { for (uint idx = 0; idx < 64; ++idx) { - int val = _sceneStats[_currentScene][idx]; + bool flag = _sceneStats[_currentScene][idx]; if (idx < _bgShapes.size()) { Object &obj = _bgShapes[idx]; - if (val & 1) { + if (flag) { // No shape to erase, so flag as hidden obj._type = HIDDEN; } else if (obj._images == nullptr || obj._images->size() == 0) { -- cgit v1.2.3 From 35368ce8a81cba7a2921a4e14036fa21290f663c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 25 Apr 2015 05:52:04 -0500 Subject: SHERLOCK: Fixes and cleanup for checkObject --- engines/sherlock/objects.cpp | 8 ++++---- engines/sherlock/objects.h | 2 +- engines/sherlock/scene.cpp | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 78b6cda2d3..6231c9abc7 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -544,7 +544,7 @@ void Object::toggleHidden() { /** * Check the state of the object */ -void Object::checkObject(Object &o) { +void Object::checkObject() { Scene &scene = *_vm->_scene; Sound &sound = *_vm->_sound; int checkFrame = _allow ? MAX_FRAME : 32000; @@ -559,9 +559,9 @@ void Object::checkObject(Object &o) { } else { // Continue doing sequence if (*ptr > _seqTo) - *ptr--; + *ptr -= 1; else - *ptr++; + *ptr += 1; return; } @@ -654,7 +654,7 @@ void Object::checkObject(Object &o) { _frameNumber += 2; } else if (v < 4) { for (int idx = 0; idx < 4; ++idx) { - o.checkNameForCodes(_use[v]._names[idx], nullptr); + checkNameForCodes(_use[v]._names[idx], nullptr); } if (_use[v]._useFlag) diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 534ed66643..2b2472fbbf 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -206,7 +206,7 @@ public: void toggleHidden(); - void checkObject(Object &o); + void checkObject(); int checkNameForCodes(const Common::String &name, const char *const messages[]); diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 3f551ef5ba..16bb8daecf 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -964,7 +964,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) { Object::_countCAnimFrames = true; while (cObj._type == ACTIVE_BG_SHAPE) { - cObj.checkObject(_bgShapes[0]); + cObj.checkObject(); ++frames; if (frames >= 1000) @@ -1035,7 +1035,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) { gotoCode = cObj._sequences[cObj._frameNumber + 3]; // Set canim to REMOVE type and free memory - cObj.checkObject(_bgShapes[0]); + cObj.checkObject(); if (gotoCode > 0 && !talk._talkToAbort) { _goToScene = gotoCode; @@ -1119,15 +1119,15 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE) - _bgShapes[idx].checkObject(_bgShapes[idx]); + _bgShapes[idx].checkObject(); } if (people._portraitLoaded && people._portrait._type == ACTIVE_BG_SHAPE) - people._portrait.checkObject(people._portrait); + people._portrait.checkObject(); for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if (_canimShapes[idx]._type != INVALID && _canimShapes[idx]._type != REMOVE) - _canimShapes[idx].checkObject(_bgShapes[0]); + _canimShapes[idx].checkObject(); } if (_currentScene == 12 && _vm->getGameID() == GType_SerratedScalpel) -- cgit v1.2.3 From 95f25329379482555c6b1e3181fc737b80f53b40 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 25 Apr 2015 18:37:45 -0500 Subject: SHERLOCK: Disable joystick buttons in Setup dialog, since it isn't supported --- engines/sherlock/user_interface.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 176b1bc42b..53151ece55 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -147,11 +147,16 @@ void Settings::drawInteface(bool flag) { screen.makeButton(Common::Rect(SETUP_POINTS[5][0], SETUP_POINTS[5][1], SETUP_POINTS[5][2], SETUP_POINTS[5][1] + 10), SETUP_POINTS[5][3] - screen.stringWidth("New Font Style") / 2, "New Font Style"); - tempStr = Common::String::format("Joystick %s", SETUP_STRS0[0]); + // WORKAROUND: We don't support the joystick in ScummVM, so draw the next two buttons as disabled + tempStr = "Joystick Off"; screen.makeButton(Common::Rect(SETUP_POINTS[6][0], SETUP_POINTS[6][1], SETUP_POINTS[6][2], SETUP_POINTS[6][1] + 10), SETUP_POINTS[6][3] - screen.stringWidth(tempStr) / 2, tempStr); + screen.buttonPrint(Common::Point(SETUP_POINTS[6][3], SETUP_POINTS[6][1]), COMMAND_NULL, false, tempStr); + + tempStr = "Calibrate Joystick"; screen.makeButton(Common::Rect(SETUP_POINTS[7][0], SETUP_POINTS[7][1], SETUP_POINTS[7][2], SETUP_POINTS[7][1] + 10), - SETUP_POINTS[7][3] - screen.stringWidth("Calibrate Joystick") / 2, "Calibrate Joystick"); + SETUP_POINTS[7][3] - screen.stringWidth(tempStr) / 2, tempStr); + screen.buttonPrint(Common::Point(SETUP_POINTS[7][3], SETUP_POINTS[7][1]), COMMAND_NULL, false, tempStr); tempStr = Common::String::format("Fade %s", screen._fadeStyle ? "by Pixel" : "Directly"); screen.makeButton(Common::Rect(SETUP_POINTS[8][0], SETUP_POINTS[8][1], SETUP_POINTS[8][2], SETUP_POINTS[8][1] + 10), @@ -164,7 +169,7 @@ void Settings::drawInteface(bool flag) { tempStr = Common::String::format("Portraits %s", SETUP_STRS0[people._portraitsOn]); screen.makeButton(Common::Rect(SETUP_POINTS[10][0], SETUP_POINTS[10][1], SETUP_POINTS[10][2], SETUP_POINTS[10][1] + 10), SETUP_POINTS[10][3] - screen.stringWidth(tempStr) / 2, tempStr); - tempStr = Common::String::format("_key Pad %s", _vm->_keyPadSpeed ? "Fast" : "Slow"); + tempStr = Common::String::format("Key Pad %s", _vm->_keyPadSpeed ? "Fast" : "Slow"); screen.makeButton(Common::Rect(SETUP_POINTS[11][0], SETUP_POINTS[11][1], SETUP_POINTS[11][2], SETUP_POINTS[11][1] + 10), SETUP_POINTS[11][3] - screen.stringWidth(tempStr) / 2, tempStr); @@ -222,8 +227,12 @@ int Settings::drawButtons(const Common::Point &pt, int _key) { screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); break; case 6: - tempStr = Common::String::format("Joystick %s", SETUP_STRS0[0]); - screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); + tempStr = "Joystick Off"; + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), COMMAND_NULL, true, tempStr); + break; + case 7: + tempStr = "Calibrate Joystick"; + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), COMMAND_NULL, true, tempStr); break; case 8: tempStr = Common::String::format("Fade %s", SETUP_STRS1[screen._fadeStyle]); @@ -238,7 +247,7 @@ int Settings::drawButtons(const Common::Point &pt, int _key) { screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); break; case 11: - tempStr = Common::String::format("_key Pad %s", SETUP_STRS4[_vm->_keyPadSpeed]); + tempStr = Common::String::format("Key Pad %s", SETUP_STRS4[_vm->_keyPadSpeed]); screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); break; default: -- cgit v1.2.3 From 1e4c6abfa3ed3df2bd33f774eddfd5e1a389b9fc Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 25 Apr 2015 21:53:50 -0500 Subject: SHERLOCK: Fix checkSceneFlags incorrectly restoring hidden objects --- engines/sherlock/scene.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 16bb8daecf..60e7b6d369 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -516,7 +516,7 @@ void Scene::checkSceneFlags(bool flag) { // Flag it as needing to be hidden after first erasing it o._type = mode; } - } else if (_bgShapes[idx]._requiredFlag) { + } else if (_bgShapes[idx]._requiredFlag > 0) { // Restore object if (o._images == nullptr || o._images->size() == 0) o._type = NO_SHAPE; -- cgit v1.2.3 From a95170d243df415e58b93e46bf9e23b068729954 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 25 Apr 2015 23:44:50 -0500 Subject: SHERLOCK: Fix Watson not appearing in backstage scene --- engines/sherlock/scene.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 60e7b6d369..ea7d517301 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -438,6 +438,7 @@ bool Scene::loadScene(const Common::String &filename) { // Player has not yet walked in this scene _walkedInScene = false; + saves._justLoaded = false; // Reset the position on the overland map _vm->_oldCharPoint = _currentScene; -- cgit v1.2.3 From 15a4a942bb6ed708b2ea15bcbb33da66cae292ac Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 26 Apr 2015 00:38:19 -0500 Subject: SHERLOCK: Fix RUN_CANIMATION talk opcode --- engines/sherlock/talk.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 2ad70dabed..4e7e4de2d0 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1114,7 +1114,8 @@ void Talk::doScript(const Common::String &script) { case RUN_CANIMATION: // Save the current point in the script, since it might be intterupted by // doing bg anims in the next call, so we need to know where to return to - _scriptCurrentIndex = str - script.c_str(); + ++str; + _scriptCurrentIndex = (str + 1) - script.c_str(); scene.startCAnim((str[0] - 1) & 127, 1 + (str[0] & 128)); if (_talkToAbort) return; -- cgit v1.2.3 From 841a8df09943d77601d1b44c63a2b0c5a531e468 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 26 Apr 2015 02:08:43 -0500 Subject: SHERLOCK: Fix Sherlock disappearing when giving sedative --- engines/sherlock/objects.cpp | 3 +++ engines/sherlock/scene.cpp | 8 +++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 6231c9abc7..e66f2a68bd 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -424,6 +424,9 @@ Object::Object() { _misc = 0; _maxFrames = 0; _flags = 0; + _aOpen._cAnimNum = 0; + _aOpen._cAnimSpeed = 0; + _aType = OBJECT; _lookFrames = 0; _seqCounter = 0; _lookFacing = 0; diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index ea7d517301..d9161e25c0 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -892,9 +892,6 @@ int Scene::startCAnim(int cAnimNum, int playRate) { CursorId oldCursor = events.getCursor(); events.setCursor(WAIT); - _canimShapes.push_back(Object()); - Object &cObj = _canimShapes[_canimShapes.size() - 1]; - if (walkPos.x != -1) { // Holmes must walk to the walk point before the cAnimation is started if (people[AL]._position != walkPos) @@ -904,6 +901,10 @@ int Scene::startCAnim(int cAnimNum, int playRate) { if (talk._talkToAbort) return 1; + // Add new anim shape entry for displaying the animationo + _canimShapes.push_back(Object()); + Object &cObj = _canimShapes[_canimShapes.size() - 1]; + // Copy the canimation into the bgShapes type canimation structure so it can be played cObj._allow = cAnimNum + 1; // Keep track of the parent structure cObj._name = _cAnim[cAnimNum]._name; // Copy name @@ -1304,6 +1305,7 @@ void Scene::doBgAnim() { people[AL]._oldPosition.x + people[AL]._oldSize.x, people[AL]._oldPosition.y + people[AL]._oldSize.y )); + people[AL]._type = INVALID; } else { screen.flushImage(people[AL]._imageFrame, Common::Point(people[AL]._position.x / 100, -- cgit v1.2.3 From 6a13dad7ef844ffd5e5174b337cf7e4ad272c80b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 26 Apr 2015 03:07:13 -0500 Subject: SHERLOCK: Fix TOGGLE_OBJECT talk opcode --- engines/sherlock/talk.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 4e7e4de2d0..d81f98cac7 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1294,6 +1294,7 @@ void Talk::doScript(const Common::String &script) { break; case TOGGLE_OBJECT: + ++str; for (int idx = 0; idx < str[0]; ++idx) tempString += str[idx + 1]; -- cgit v1.2.3 From d7a8d701641600b896622f8b7abb728c4b4cc266 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 26 Apr 2015 03:20:01 -0500 Subject: SHERLOCK: Fix missing increments from various talk opcodes --- engines/sherlock/talk.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index d81f98cac7..b45139db4e 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1212,6 +1212,7 @@ void Talk::doScript(const Common::String &script) { case WALK_TO_COORDS: // Save the current point in the script, since it might be intterupted by // doing bg anims in the next call, so we need to know where to return to + ++str; _scriptCurrentIndex = str - script.c_str(); people.walkToCoords(Common::Point(((str[0] - 1) * 256 + str[1] - 1) * 100, str[2] * 100), str[3] - 1); @@ -1224,6 +1225,7 @@ void Talk::doScript(const Common::String &script) { case PAUSE_WITHOUT_CONTROL: // Save the current point in the script, since it might be intterupted by // doing bg anims in the next call, so we need to know where to return to + ++str; _scriptCurrentIndex = str - script.c_str(); for (int idx = 0; idx < (str[0] - 1); ++idx) { @@ -1433,6 +1435,7 @@ void Talk::doScript(const Common::String &script) { case MOVE_MOUSE: // Save the current point in the script, since it might be intterupted by // doing bg anims in the next call, so we need to know where to return to + ++str; _scriptCurrentIndex = str - script.c_str(); events.moveMouse(Common::Point((str[0] - 1) * 256 + str[1] - 1, str[2])); if (_talkToAbort) -- cgit v1.2.3 From 9044dd49dc2debd1c7d1fa4ea991320a1072235e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 26 Apr 2015 03:45:28 -0500 Subject: SHERLOCK: Fix closing closet in Backstage scene --- engines/sherlock/objects.cpp | 4 ++++ engines/sherlock/objects.h | 4 ++-- engines/sherlock/user_interface.cpp | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index e66f2a68bd..8c8d90579c 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -366,6 +366,8 @@ void ActionType::synchronize(Common::SeekableReadStream &s) { _cAnimNum = s.readByte(); _cAnimSpeed = s.readByte(); + if (_cAnimSpeed & 0x80) + _cAnimSpeed = -(_cAnimSpeed & 0x7f); for (int idx = 0; idx < 4; ++idx) { s.read(buffer, 12); @@ -380,6 +382,8 @@ void UseType::synchronize(Common::SeekableReadStream &s) { _cAnimNum = s.readByte(); _cAnimSpeed = s.readByte(); + if (_cAnimSpeed & 0x80) + _cAnimSpeed = -(_cAnimSpeed & 0x7f); for (int idx = 0; idx < 4; ++idx) { s.read(buffer, 12); diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 2b2472fbbf..80b0b9d9f3 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -125,8 +125,8 @@ public: enum { REVERSE_DIRECTION = 0x80 }; struct ActionType { - int8 _cAnimNum; - uint8 _cAnimSpeed; // if high bit set, play in reverse + int _cAnimNum; + int _cAnimSpeed; // if high bit set, play in reverse Common::String _names[4]; void synchronize(Common::SeekableReadStream &s); diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 53151ece55..c623896c85 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -2678,7 +2678,7 @@ void UserInterface::checkAction(ActionType &action, const char *const messages[] if (scene._goToScene != 1 && !printed && !talk._talkToAbort) { _infoFlag = true; clearInfo(); - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, messages[action._cAnimNum]); + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "Done..."); // Set how long to show the message _menuCounter = 30; -- cgit v1.2.3 From 0c68c0a53ac2ffb5837ca2eada00af7f371bc7c9 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 26 Apr 2015 04:33:24 -0500 Subject: SHERLOCK: Fix inventory display when player has more than 6 items --- engines/sherlock/inventory.cpp | 6 +++--- engines/sherlock/user_interface.cpp | 31 ++++++++++++------------------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index 808429f643..798531ea14 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -120,7 +120,7 @@ void Inventory::loadGraphics() { int invNum = findInv((*this)[idx]._name); Common::String fName = Common::String::format("item%02d.vgs", invNum + 1); - _invShapes[idx] = new ImageFile(fName); + _invShapes[idx - _invIndex] = new ImageFile(fName); } _invGraphicsLoaded = true; @@ -302,10 +302,10 @@ void Inventory::invCommands(bool slamIt) { _invMode == 3 ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, true, "Give"); screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1), - _invMode == 0 ? COMMAND_NULL : COMMAND_FOREGROUND, + _invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND, "^^"); screen.print(Common::Point(INVENTORY_POINTS[5][2], CONTROLS_Y1 + 1), - _invMode == 0 ? COMMAND_NULL : COMMAND_FOREGROUND, + _invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND, "^"); screen.print(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1 + 1), (_holdings - _invIndex <= 6) ? COMMAND_NULL : COMMAND_FOREGROUND, diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index c623896c85..7a581ca63b 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1247,17 +1247,13 @@ void UserInterface::doInvControl() { } if (inv._invIndex) { - screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1), - colors[4], "^^"); - screen.print(Common::Point(INVENTORY_POINTS[5][2], CONTROLS_Y1 + 1), - colors[5], "^"); + screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1), colors[4], "^^"); + screen.print(Common::Point(INVENTORY_POINTS[5][2], CONTROLS_Y1 + 1), colors[5], "^"); } if ((inv._holdings - inv._invIndex) > 6) { - screen.print(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1 + 1), - colors[6], "^^"); - screen.print(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1 + 1), - colors[7], "^"); + screen.print(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1 + 1), colors[6], "_"); + screen.print(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1 + 1), colors[7], "__"); } bool flag = false; @@ -1339,31 +1335,28 @@ void UserInterface::doInvControl() { inv.loadGraphics(); inv.putInv(1); inv.invCommands(true); - } else if (((found == 5 && events._released) || _key == '-') && inv._invIndex) { + } else if (((found == 5 && events._released) || _key == Common::KEYCODE_MINUS + || _key == Common::KEYCODE_KP_MINUS) && inv._invIndex > 0) { --inv._invIndex; - screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1), - COMMAND_HIGHLIGHTED, "^"); + screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1), COMMAND_HIGHLIGHTED, "^"); inv.freeGraphics(); inv.loadGraphics(); inv.putInv(1); inv.invCommands(true); - } else if (((found == 6 && events._released) || _key == '+') && - (inv._holdings - inv._invIndex) > 6) { + } else if (((found == 6 && events._released) || _key == Common::KEYCODE_PLUS + || _key == Common::KEYCODE_KP_PLUS) && (inv._holdings - inv._invIndex) > 6) { ++inv._invIndex; - screen.print(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1 + 1), - COMMAND_HIGHLIGHTED, "_"); + screen.print(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1 + 1), COMMAND_HIGHLIGHTED, "_"); inv.freeGraphics(); inv.loadGraphics(); inv.putInv(1); inv.invCommands(true); - } else if (((found == 7 && events._released) || _key == '.') && - (inv._holdings - inv._invIndex) > 6) { + } else if (((found == 7 && events._released) || _key == '.') && (inv._holdings - inv._invIndex) > 6) { inv._invIndex += 6; if ((inv._holdings - 6) < inv._invIndex) inv._invIndex = inv._holdings - 6; - screen.print(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1 + 1), - COMMAND_HIGHLIGHTED, "_"); + screen.print(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1 + 1), COMMAND_HIGHLIGHTED, "_"); inv.freeGraphics(); inv.loadGraphics(); inv.putInv(1); -- cgit v1.2.3 From 250b3c1a30acba5770f214edaf14bc288065acd9 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 26 Apr 2015 04:52:31 -0500 Subject: SHERLOCK: Fix handling of talk opcodes in journal loading --- engines/sherlock/journal.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index ffda25a533..255662f71c 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -356,23 +356,23 @@ int Journal::loadJournalFile(bool alreadyLoaded) { break; case 134: // Change sequence - replyP += (replyP[0] & 127) + replyP[2] + 1; + replyP += (replyP[0] & 127) + replyP[2] + 2; break; case 135: // Walk to co-ords case 154: // Move mouse - replyP += 3; + replyP += 4; break; case 139: // Set flag case 143: // If statement - ++replyP; + replyP += 2; break; case 140: // Play voice file case 150: // Play prologue case 153: // Call talk file - replyP += 7; + replyP += 8; break; case 141: // Toggle object @@ -380,11 +380,11 @@ int Journal::loadJournalFile(bool alreadyLoaded) { case 152: // Set object case 155: // Info line case 158: // Delete item from inventory - replyP += *replyP & 127; + replyP += (*replyP & 127) + 1; break; case 149: // Goto scene - replyP += 4; + replyP += 5; break; case 161: // End of line -- cgit v1.2.3 From fd8cab4ffd38574fd255bd8f6335238ceb19bba8 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 26 Apr 2015 06:22:25 -0500 Subject: SHERLOCK: Fix casting of data in talk opcode handling --- engines/sherlock/talk.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index b45139db4e..fafd9ce201 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1027,7 +1027,7 @@ void Talk::doScript(const Common::String &script) { } // Check if the script begins with a Stealh Mode Active command - if (str[0] == STEALTH_MODE_ACTIVE || _talkStealth) { + if ((byte)str[0] == STEALTH_MODE_ACTIVE || _talkStealth) { _talkStealth = 2; _speaker |= 128; } else { @@ -1068,7 +1068,7 @@ void Talk::doScript(const Common::String &script) { } // Remove portrait? - if (str[0] == REMOVE_PORTRAIT) { + if ((byte)str[0] == REMOVE_PORTRAIT) { _speaker = 255; } else { // Nope, so set the first speaker @@ -1116,12 +1116,12 @@ void Talk::doScript(const Common::String &script) { // doing bg anims in the next call, so we need to know where to return to ++str; _scriptCurrentIndex = (str + 1) - script.c_str(); - scene.startCAnim((str[0] - 1) & 127, 1 + (str[0] & 128)); + scene.startCAnim(((byte)str[0] - 1) & 127, 1 + ((byte)str[0] & 128)); if (_talkToAbort) return; // Check if next character is changing side or changing portrait - if (charCount && (str[1] == SWITCH_SPEAKER || str[1] == ASSIGN_PORTRAIT_LOCATION)) + if (charCount && ((byte)str[1] == SWITCH_SPEAKER || (byte)str[1] == ASSIGN_PORTRAIT_LOCATION)) wait = 1; break; @@ -1215,7 +1215,8 @@ void Talk::doScript(const Common::String &script) { ++str; _scriptCurrentIndex = str - script.c_str(); - people.walkToCoords(Common::Point(((str[0] - 1) * 256 + str[1] - 1) * 100, str[2] * 100), str[3] - 1); + people.walkToCoords(Common::Point((((byte)str[0] - 1) * 256 + (byte)str[1] - 1) * 100, + (byte)str[2] * 100), str[3] - 1); if (_talkToAbort) return; @@ -1272,7 +1273,7 @@ void Talk::doScript(const Common::String &script) { case SET_FLAG: { ++str; - int flag1 = (str[0] - 1) * 256 + str[1] - 1 - (str[1] == 1 ? 1 : 0); + int flag1 = ((byte)str[0] - 1) * 256 + (byte)str[1] - 1 - (str[1] == 1 ? 1 : 0); int flag = (flag1 & 0x7fff) * (flag1 >= 0x8000 ? -1 : 1); _vm->setFlags(flag); ++str; @@ -1310,7 +1311,7 @@ void Talk::doScript(const Common::String &script) { case IF_STATEMENT: { ++str; - int flag = (str[0] - 1) * 256 + str[1] - 1 - (str[1] == 1 ? 1 : 0); + int flag = ((byte)str[0] - 1) * 256 + (byte)str[1] - 1 - (str[1] == 1 ? 1 : 0); ++str; wait = 0; @@ -1396,7 +1397,7 @@ void Talk::doScript(const Common::String &script) { str += str[0]; // Set comparison state according to if we want to hide or unhide - bool state = (str[0] >= 128); + bool state = ((byte)str[0] >= 128); for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) { Object &obj = scene._bgShapes[idx]; @@ -1437,7 +1438,7 @@ void Talk::doScript(const Common::String &script) { // doing bg anims in the next call, so we need to know where to return to ++str; _scriptCurrentIndex = str - script.c_str(); - events.moveMouse(Common::Point((str[0] - 1) * 256 + str[1] - 1, str[2])); + events.moveMouse(Common::Point(((byte)str[0] - 1) * 256 + (byte)str[1] - 1, str[2])); if (_talkToAbort) return; str += 3; @@ -1599,7 +1600,7 @@ void Talk::doScript(const Common::String &script) { } // Open window if it wasn't already open, and text has already been printed - if ((openTalkWindow && wait) || (openTalkWindow && str[0] >= 128 && str[0] != COMMAND_161)) { + if ((openTalkWindow && wait) || (openTalkWindow && (byte)str[0] >= 128 && (byte)str[0] != COMMAND_161)) { if (!ui._windowStyle) { screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); } else { @@ -1625,12 +1626,12 @@ void Talk::doScript(const Common::String &script) { // If a key was pressed to finish the window, see if further voice files should be skipped if (wait >= 0 && wait < 254) { - if (str[0] == SFX_COMMAND) + if ((byte)str[0] == SFX_COMMAND) str += 9; } // Clear the window unless the wait was due to a PAUSE command - if (!pauseFlag && wait != -1 && str[0] != SFX_COMMAND) { + if (!pauseFlag && wait != -1 && (byte)str[0] != SFX_COMMAND) { if (!_talkStealth) ui.clearWindow(); yp = CONTROLS_Y + 12; -- cgit v1.2.3 From 0ca3fd645406a44f272ccc77abbc143523918701 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 26 Apr 2015 16:38:34 -0500 Subject: SHERLOCK: Fix SET_FLAG talk opcode --- engines/sherlock/talk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index fafd9ce201..c605f9a7e9 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1274,7 +1274,7 @@ void Talk::doScript(const Common::String &script) { case SET_FLAG: { ++str; int flag1 = ((byte)str[0] - 1) * 256 + (byte)str[1] - 1 - (str[1] == 1 ? 1 : 0); - int flag = (flag1 & 0x7fff) * (flag1 >= 0x8000 ? -1 : 1); + int flag = (flag1 & 0x3fff) * (flag1 >= 0x4000 ? -1 : 1); _vm->setFlags(flag); ++str; break; -- cgit v1.2.3 From 488ac579d7cd037dfe5c71cf20a878cf5ecdfe18 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 26 Apr 2015 17:26:22 -0500 Subject: SHERLOCK: Fix checking single character star action names --- engines/sherlock/objects.cpp | 2 +- engines/sherlock/user_interface.cpp | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 8c8d90579c..49f64c85b0 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -828,7 +828,7 @@ int Object::checkNameForCodes(const Common::String &name, const char *const mess if (name.hasPrefix("*")) { // A code was found printed = true; - ch = toupper(name[1]); + ch = (name == "*") ? 0 : toupper(name[1]); switch (ch) { case 'C': diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 7a581ca63b..ed3debe2fc 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -2609,7 +2609,8 @@ void UserInterface::checkAction(ActionType &action, const char *const messages[] events.setCursor(WAIT); for (int nameIdx = 0; nameIdx < 4; ++nameIdx) { - if (action._names[nameIdx].hasPrefix("*") && toupper(action._names[nameIdx][1]) == 'W') { + if (action._names[nameIdx].hasPrefix("*") && action._names[nameIdx].size() >= 2 + && toupper(action._names[nameIdx][1]) == 'W') { if (obj.checkNameForCodes(Common::String(action._names[nameIdx].c_str() + 2), messages)) { if (!talk._talkToAbort) printed = true; @@ -2618,7 +2619,7 @@ void UserInterface::checkAction(ActionType &action, const char *const messages[] } for (int nameIdx = 0; nameIdx < 4; ++nameIdx) { - if (action._names[nameIdx].hasPrefix("*")) { + if (action._names[nameIdx].hasPrefix("*") && action._names[nameIdx].size() >= 2) { char ch = toupper(action._names[nameIdx][1]); if (ch == 'T' || ch == 'B') { @@ -2648,7 +2649,8 @@ void UserInterface::checkAction(ActionType &action, const char *const messages[] } for (int nameIdx = 0; nameIdx < 4; ++nameIdx) { - if (action._names[nameIdx].hasPrefix("*") && toupper(action._names[nameIdx][1]) == 'F') { + if (action._names[nameIdx].hasPrefix("*") && action._names[nameIdx].size() >= 2 + && toupper(action._names[nameIdx][1]) == 'F') { if (obj.checkNameForCodes(action._names[nameIdx].c_str() + 2, messages)) { if (!talk._talkToAbort) printed = true; -- cgit v1.2.3 From f3bd61607017fe0ef0f5143e6ad8dbdb4743b246 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 26 Apr 2015 18:07:52 -0500 Subject: SHERLOCK: Fix character positioning after loading savegames --- engines/sherlock/objects.cpp | 22 +++++++++++----------- engines/sherlock/people.cpp | 13 ++++++++++--- engines/sherlock/people.h | 2 ++ engines/sherlock/scalpel/scalpel.cpp | 4 ++-- engines/sherlock/scene.cpp | 34 +++++++++++++++++----------------- engines/sherlock/scene.h | 2 -- engines/sherlock/sherlock.cpp | 2 +- engines/sherlock/talk.cpp | 4 ++-- 8 files changed, 45 insertions(+), 38 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 49f64c85b0..7341fc3b30 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -165,11 +165,11 @@ void Sprite::adjustSprite() { scene._goToScene = exit->_scene; if (exit->_people.x != 0) { - scene._hsavedPos = exit->_people; - scene._hsavedFs = exit->_peopleDir; + people._hSavedPos = exit->_people; + people._hSavedFacing = exit->_peopleDir; - if (scene._hsavedFs > 100 && scene._hsavedPos.x < 1) - scene._hsavedPos.x = 100; + if (people._hSavedFacing > 100 && people._hSavedPos.x < 1) + people._hSavedPos.x = 100; } } } @@ -869,18 +869,18 @@ int Object::checkNameForCodes(const Common::String &name, const char *const mess ++p; Common::String s(p, p + 3); - scene._hsavedPos.x = atoi(s.c_str()); + people._hSavedPos.x = atoi(s.c_str()); s = Common::String(p + 3, p + 6); - scene._hsavedPos.y = atoi(s.c_str()); + people._hSavedPos.y = atoi(s.c_str()); s = Common::String(p + 6, p + 9); - scene._hsavedFs = atoi(s.c_str()); - if (scene._hsavedFs == 0) - scene._hsavedFs = 10; + people._hSavedFacing = atoi(s.c_str()); + if (people._hSavedFacing == 0) + people._hSavedFacing = 10; } else if ((p = strchr(name.c_str(), '/')) != nullptr) { - scene._hsavedPos = Common::Point(1, 0); - scene._hsavedFs = 100 + atoi(p + 1); + people._hSavedPos = Common::Point(1, 0); + people._hSavedFacing = 100 + atoi(p + 1); } } else { scene._goToScene = 100; diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index e126757231..43e1fa046b 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -204,6 +204,8 @@ People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) { _speakerFlip = false; _holmesFlip = false; _holmesQuotient = 0; + _hSavedPos = Common::Point(-1, -1); + _hSavedFacing = -1; _portrait._sequences = new byte[32]; } @@ -708,10 +710,15 @@ void People::setTalking(int speaker) { */ void People::synchronize(Common::Serializer &s) { s.syncAsByte(_holmesOn); - s.syncAsSint16LE(_data[AL]._position.x); - s.syncAsSint16LE(_data[AL]._position.y); - s.syncAsSint16LE(_data[AL]._sequenceNumber); + s.syncAsSint16LE(_player._position.x); + s.syncAsSint16LE(_player._position.y); + s.syncAsSint16LE(_player._sequenceNumber); s.syncAsSint16LE(_holmesQuotient); + + if (s.isLoading()) { + _hSavedPos = _player._position; + _hSavedFacing = _player._sequenceNumber; + } } } // End of namespace Sherlock diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index 8a7476a33a..f1ed3496a1 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -74,6 +74,8 @@ private: public: ImageFile *_talkPics; Common::Point _walkDest; + Common::Point _hSavedPos; + int _hSavedFacing; Common::Queue _walkTo; Person &_player; bool _holmesOn; diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 2ca9f80c42..65ca61b09f 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -479,8 +479,8 @@ void ScalpelEngine::startScene() { _scene->_goToScene = _map->show(); _sound->freeSong(); - _scene->_hsavedPos = Common::Point(-1, -1); - _scene->_hsavedFs = -1; + _people->_hSavedPos = Common::Point(-1, -1); + _people->_hSavedFacing = -1; } // Some rooms are prologue cutscenes, rather than normal game scenes. These are: diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index d9161e25c0..2d0f6fd751 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -97,8 +97,6 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { _version = 0; _lzwMode = false; _invGraphicItems = 0; - _hsavedPos = Common::Point(-1, -1); - _hsavedFs = -1; _cAnimFramePause = 0; _restoreFlag = false; _invLookFlag = false; @@ -579,48 +577,50 @@ void Scene::transitionToScene() { SaveManager &saves = *_vm->_saves; Screen &screen = *_vm->_screen; Talk &talk = *_vm->_talk; + Common::Point &hSavedPos = people._hSavedPos; + int &hSavedFacing = people._hSavedFacing; const int FS_TRANS[8] = { STOP_UP, STOP_UPRIGHT, STOP_RIGHT, STOP_DOWNRIGHT, STOP_DOWN, STOP_DOWNLEFT, STOP_LEFT, STOP_UPLEFT }; - if (_hsavedPos.x < 1) { + if (hSavedPos.x < 1) { // No exit information from last scene-check entrance info if (_entrance._startPosition.x < 1) { // No entrance info either, so use defaults - _hsavedPos = Common::Point(16000, 10000); - _hsavedFs = 4; + hSavedPos = Common::Point(16000, 10000); + hSavedFacing = 4; } else { // setup entrance info - _hsavedPos = _entrance._startPosition; - _hsavedFs = _entrance._startDir; + hSavedPos = _entrance._startPosition; + hSavedFacing = _entrance._startDir; } } else { // Exit information exists, translate it to real sequence info // Note: If a savegame was just loaded, then the data is already correct. // Otherwise, this is a linked scene or entrance info, and must be translated - if (_hsavedFs < 8 && !saves._justLoaded) { - _hsavedFs = FS_TRANS[_hsavedFs]; - _hsavedPos.x *= 100; - _hsavedPos.y *= 100; + if (hSavedFacing < 8 && !saves._justLoaded) { + hSavedFacing = FS_TRANS[hSavedFacing]; + hSavedPos.x *= 100; + hSavedPos.y *= 100; } } int cAnimNum = -1; - if (_hsavedFs < 101) { + if (hSavedFacing < 101) { // Standard info, so set it - people[PLAYER]._position = _hsavedPos; - people[PLAYER]._sequenceNumber = _hsavedFs; + people[PLAYER]._position = hSavedPos; + people[PLAYER]._sequenceNumber = hSavedFacing; } else { // It's canimation information - cAnimNum = _hsavedFs - 101; + cAnimNum = hSavedFacing - 101; } // Reset positioning for next load - _hsavedPos = Common::Point(-1, -1); - _hsavedFs = -1; + hSavedPos = Common::Point(-1, -1); + hSavedFacing = -1; if (cAnimNum != -1) { // Prevent Holmes from being drawn diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index cc01fa92ab..892163a2f6 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -130,8 +130,6 @@ public: Common::Array _exits; SceneEntry _entrance; Common::Array _sounds; - Common::Point _hsavedPos; - int _hsavedFs; Common::Array _canimShapes; bool _restoreFlag; int _animating; diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index d880257406..406b796fc9 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -147,7 +147,7 @@ void SherlockEngine::sceneLoop() { // Handle any input from the keyboard or mouse handleInput(); - if (_scene->_hsavedPos.x == -1) { + if (_people->_hSavedPos.x == -1) { _canLoadSave = true; _scene->doBgAnim(); _canLoadSave = false; diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index c605f9a7e9..0793552846 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1361,8 +1361,8 @@ void Talk::doScript(const Common::String &script) { // Run a canimation? if (str[2] > 100) { - scene._hsavedFs = str[2]; - scene._hsavedPos = Common::Point(160, 100); + people._hSavedFacing = (byte)str[2]; + people._hSavedPos = Common::Point(160, 100); } } str += 6; -- cgit v1.2.3 From 65eb390ead25c54b1e3c547f3e189a7ccb73becb Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 26 Apr 2015 18:29:20 -0500 Subject: SHERLOCK: Cleanup and moving of map variables into Map class --- engines/sherlock/map.cpp | 29 +++++++++++++++++++++-------- engines/sherlock/map.h | 8 ++++++-- engines/sherlock/objects.cpp | 4 ++-- engines/sherlock/people.cpp | 5 ++--- engines/sherlock/saveload.cpp | 2 ++ engines/sherlock/scalpel/scalpel.cpp | 18 +++++++++--------- engines/sherlock/scene.cpp | 18 +++++------------- engines/sherlock/scene.h | 3 --- engines/sherlock/sherlock.h | 2 -- engines/sherlock/talk.cpp | 6 +++--- 10 files changed, 50 insertions(+), 45 deletions(-) diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index c3a5ba7b17..5865f34fa0 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -62,6 +62,9 @@ Map::Map(SherlockEngine *vm): _vm(vm), _topLine(SHERLOCK_SCREEN_WIDTH, 12) { _cursorIndex = -1; _drawMap = false; _overPos = Common::Point(13000, 12600); + _charPoint = 0; + _oldCharPoint = 39; + for (int idx = 0; idx < MAX_HOLMES_SEQUENCE; ++idx) Common::fill(&_sequences[idx][0], &_sequences[idx][MAX_FRAME], 0); @@ -126,7 +129,6 @@ void Map::loadData() { int Map::show() { Events &events = *_vm->_events; People &people = *_vm->_people; - Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; Common::Point lDrawn(-1, -1); bool changed = false, exitFlag = false; @@ -230,7 +232,7 @@ int Map::show() { if ((events._released || events._rightReleased) && _point != -1) { if (people[AL]._walkCount == 0) { people._walkDest = _points[_point] + Common::Point(4, 9); - scene._charPoint = _point; + _charPoint = _point; // Start walking to selected location walkTheStreets(); @@ -243,7 +245,7 @@ int Map::show() { // Check if a scene has beeen selected and we've finished "moving" to it if (people[AL]._walkCount == 0) { - if (scene._charPoint >= 1 && scene._charPoint < (int)_points.size()) + if (_charPoint >= 1 && _charPoint < (int)_points.size()) exitFlag = true; } @@ -267,7 +269,7 @@ int Map::show() { screen.setFont(oldFont); _active = false; - return scene._charPoint; + return _charPoint; } /** @@ -443,8 +445,8 @@ void Map::walkTheStreets() { Common::Array tempPath; // Get indexes into the path lists for the start and destination scenes - int start = _points[scene._oldCharPoint]._translate; - int dest = _points[scene._charPoint]._translate; + int start = _points[_oldCharPoint]._translate; + int dest = _points[_charPoint]._translate; // Get pointer to start of path const byte *path = _paths.getPath(start, dest); @@ -454,10 +456,10 @@ void Map::walkTheStreets() { Common::Point destPos = people._walkDest; // Check for any intermediate points between the two locations - if (path[0] || scene._charPoint > 50 || scene._oldCharPoint > 50) { + if (path[0] || _charPoint > 50 || _oldCharPoint > 50) { people[AL]._sequenceNumber = -1; - if (scene._charPoint == 51 || scene._oldCharPoint == 51) { + if (_charPoint == 51 || _oldCharPoint == 51) { people.setWalking(); } else { // Check for moving the path backwards or forwards @@ -583,4 +585,15 @@ void Map::highlightIcon(const Common::Point &pt) { } } +/** +* Synchronize the data for a savegame +*/ +void Map::synchronize(Common::Serializer &s) { + s.syncAsSint16LE(_bigPos.x); + s.syncAsSint16LE(_bigPos.y); + s.syncAsSint16LE(_overPos.x); + s.syncAsSint16LE(_overPos.y); + s.syncAsSint16LE(_oldCharPoint); +} + } // End of namespace Sherlock diff --git a/engines/sherlock/map.h b/engines/sherlock/map.h index a91e7ae968..564ae73691 100644 --- a/engines/sherlock/map.h +++ b/engines/sherlock/map.h @@ -26,6 +26,7 @@ #include "common/scummsys.h" #include "common/array.h" #include "common/rect.h" +#include "common/serializer.h" #include "common/str.h" #include "common/str-array.h" #include "sherlock/graphics.h" @@ -67,8 +68,6 @@ private: ImageFile *_shapes; ImageFile *_iconShapes; byte _sequences[MAX_HOLMES_SEQUENCE][MAX_FRAME]; - Common::Point _bigPos; - Common::Point _overPos; Common::Point _lDrawnPos; int _point; bool _placesShown; @@ -97,6 +96,9 @@ private: void highlightIcon(const Common::Point &pt); public: bool _active; + Common::Point _overPos; + Common::Point _bigPos; + int _charPoint, _oldCharPoint; public: Map(SherlockEngine *vm); @@ -106,6 +108,8 @@ public: void loadSequences(int count, const byte *seq); int show(); + + void synchronize(Common::Serializer &s); }; } // End of namespace Sherlock diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 7341fc3b30..62a1a35f4a 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -861,8 +861,8 @@ int Object::checkNameForCodes(const Common::String &name, const char *const mess scene._goToScene = atoi(name.c_str() + 1); if (scene._goToScene < 97 && map[scene._goToScene].x) { - _vm->_over.x = map[scene._goToScene].x * 100 - 600; - _vm->_over.y = map[scene._goToScene].y * 100 + 900; + map._overPos.x = map[scene._goToScene].x * 100 - 600; + map._overPos.y = map[scene._goToScene].y * 100 + 900; } if ((p = strchr(name.c_str(), ',')) != nullptr) { diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 43e1fa046b..2eff1a0973 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -421,7 +421,6 @@ void People::setWalking() { */ void People::gotoStand(Sprite &sprite) { Map &map = *_vm->_map; - Scene &scene = *_vm->_scene; _walkTo.clear(); sprite._walkCount = 0; @@ -454,8 +453,8 @@ void People::gotoStand(Sprite &sprite) { if (map._active) { sprite._sequenceNumber = 0; - _data[AL]._position.x = (map[scene._charPoint].x - 6) * 100; - _data[AL]._position.y = (map[scene._charPoint].x + 10) * 100; + _player._position.x = (map[map._charPoint].x - 6) * 100; + _player._position.y = (map[map._charPoint].x + 10) * 100; } _oldWalkSequence = -1; diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index a694e21b28..86a4e8417a 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -368,6 +368,7 @@ Common::String SaveManager::generateSaveName(int slot) { void SaveManager::synchronize(Common::Serializer &s) { Inventory &inv = *_vm->_inventory; Journal &journal = *_vm->_journal; + Map &map = *_vm->_map; People &people = *_vm->_people; Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; @@ -378,6 +379,7 @@ void SaveManager::synchronize(Common::Serializer &s) { inv.synchronize(s); journal.synchronize(s); people.synchronize(s); + map.synchronize(s); scene.synchronize(s); screen.synchronize(s); talk.synchronize(s); diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 65ca61b09f..89e042d382 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -576,23 +576,23 @@ void ScalpelEngine::startScene() { switch (_scene->_goToScene) { case 52: _scene->_goToScene = 27; // Go to the Lawyer's Office - _scene->_bigPos = Common::Point(0, 0); // Overland scroll position - _scene->_overPos = Common::Point(22900 - 600, 9400 + 900); // Overland position - _scene->_oldCharPoint = 27; + _map->_bigPos = Common::Point(0, 0); // Overland scroll position + _map->_overPos = Common::Point(22900 - 600, 9400 + 900); // Overland position + _map->_oldCharPoint = 27; break; case 53: _scene->_goToScene = 17; // Go to St. Pancras Station - _scene->_bigPos = Common::Point(0, 0); // Overland scroll position - _scene->_overPos = Common::Point(32500 - 600, 3000 + 900); // Overland position - _scene->_oldCharPoint = 17; + _map->_bigPos = Common::Point(0, 0); // Overland scroll position + _map->_overPos = Common::Point(32500 - 600, 3000 + 900); // Overland position + _map->_oldCharPoint = 17; break; default: _scene->_goToScene = 4; // Back to Baker st. - _scene->_bigPos = Common::Point(0, 0); // Overland scroll position - _scene->_overPos = Common::Point(14500 - 600, 8400 + 900); // Overland position - _scene->_oldCharPoint = 4; + _map->_bigPos = Common::Point(0, 0); // Overland scroll position + _map->_overPos = Common::Point(14500 - 600, 8400 + 900); // Overland position + _map->_oldCharPoint = 4; break; } diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 2d0f6fd751..7c31788a2f 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -89,8 +89,6 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { _currentScene = -1; _goToScene = -1; _changes = false; - _charPoint = 0; - _oldCharPoint = 39; _keyboardInput = 0; _walkedInScene = false; _ongoingCans = 0; @@ -438,10 +436,10 @@ bool Scene::loadScene(const Common::String &filename) { _walkedInScene = false; saves._justLoaded = false; - // Reset the position on the overland map - _vm->_oldCharPoint = _currentScene; - _vm->_over.x = map[_currentScene].x * 100 - 600; - _vm->_over.y = map[_currentScene].y * 100 + 900; + // Reset the previous map location and position on overhead map + map._oldCharPoint = _currentScene; + map._overPos.x = map[_currentScene].x * 100 - 600; + map._overPos.y = map[_currentScene].y * 100 + 900; events.clearEvents(); return flag; @@ -1043,7 +1041,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) { _goToScene = gotoCode; if (_goToScene < 97 && map[_goToScene].x) { - _overPos = map[_goToScene]; + map._overPos = map[_goToScene]; } } @@ -1474,12 +1472,6 @@ void Scene::synchronize(Common::Serializer &s) { if (s.isSaving()) saveSceneStatus(); - s.syncAsSint16LE(_bigPos.x); - s.syncAsSint16LE(_bigPos.y); - s.syncAsSint16LE(_overPos.x); - s.syncAsSint16LE(_overPos.y); - s.syncAsSint16LE(_oldCharPoint); - if (s.isSaving()) s.syncAsSint16LE(_currentScene); else diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 892163a2f6..159f281bdf 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -107,9 +107,6 @@ public: bool _changes; bool _sceneStats[SCENES_COUNT][65]; bool _savedStats[SCENES_COUNT][9]; - Common::Point _bigPos; - Common::Point _overPos; - int _charPoint, _oldCharPoint; int _keyboardInput; int _oldKey, _help, _oldHelp; int _oldTemp, _temp; diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index ce126c0dcc..921559183d 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -104,8 +104,6 @@ public: Common::String _titleOverride; bool _useEpilogue2; bool _loadingSavedGame; - int _oldCharPoint; // Old scene - Common::Point _over; // Old map position bool _slowChess; int _keyPadSpeed; int _loadGameSlot; diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 0793552846..94779ae760 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1355,9 +1355,9 @@ void Talk::doScript(const Common::String &script) { if (scene._goToScene != 100) { // Not going to the map overview - scene._oldCharPoint = scene._goToScene; - scene._overPos.x = map[scene._goToScene].x * 100 - 600; - scene._overPos.y = map[scene._goToScene].y * 100 + 900; + map._oldCharPoint = scene._goToScene; + map._overPos.x = map[scene._goToScene].x * 100 - 600; + map._overPos.y = map[scene._goToScene].y * 100 + 900; // Run a canimation? if (str[2] > 100) { -- cgit v1.2.3 From d51173cd114e3dacabf7bfa6053f484512ad3514 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 26 Apr 2015 20:09:59 -0500 Subject: SHERLOCK: Fix map not displaying second time it's called --- engines/sherlock/map.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index 5865f34fa0..b0cf246e52 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -88,7 +88,6 @@ void Map::loadSequences(int count, const byte *seq) { Common::copy(seq, seq + MAX_FRAME, &_sequences[idx][0]); } - /** * Load data needed for the map */ @@ -151,6 +150,7 @@ int Map::show() { screen._backBuffer1.blitFrom(bigMap[3], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y)); _drawMap = true; + _charPoint = -1; _point = -1; people[AL]._position = _lDrawnPos = _overPos; -- cgit v1.2.3 From 8ec6e58f67e9dd6d0f7243d284497524280f7532 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 26 Apr 2015 20:28:49 -0500 Subject: SHERLOCK: Fix color for picking up messages --- engines/sherlock/objects.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 62a1a35f4a..f662d00aed 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -994,7 +994,7 @@ int Object::pickUpObject(const char *const messages[]) { ++ui._infoFlag; ui.clearInfo(); - screen.print(Common::Point(0, INFO_LINE + 1), INFO_LINE, messages[message]); + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, messages[message]); ui._menuCounter = 30; } else { // Pick it up -- cgit v1.2.3 From 3d483400698526a79fe31ac440bb2c410889f85f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 26 Apr 2015 21:15:33 -0500 Subject: SHERLOCK: Fix using items from inventory dialog --- engines/sherlock/user_interface.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index ed3debe2fc..97f6cfd63a 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -766,7 +766,7 @@ void UserInterface::lookScreen(const Common::Point &pt) { Common::Point mousePos = events.mousePos(); int temp; Common::String tempStr; - int x, width, width1, width2 = 0; + int x, width; // Don't display anything for right button command if ((events._rightPressed || events._rightPressed) && !events._pressed) @@ -790,7 +790,7 @@ void UserInterface::lookScreen(const Common::Point &pt) { // If inventory is active and an item is selected for a Use or Give action if ((_menuMode == INV_MODE || _menuMode == USE_MODE || _menuMode == GIVE_MODE) && (inv._invMode == 2 || inv._invMode == 3)) { - width1 = screen.stringWidth(inv[_selector]._name); + int width1 = 0, width2 = 0; if (inv._invMode == 2) { // Using an object @@ -805,6 +805,7 @@ void UserInterface::lookScreen(const Common::Point &pt) { // If we're using an inventory object, add in the width // of the object name and the " on " if (_selector != -1) { + width1 = screen.stringWidth(inv[_selector]._name); x += width1; width2 = screen.stringWidth(" on "); x += width2; @@ -835,6 +836,7 @@ void UserInterface::lookScreen(const Common::Point &pt) { } else if (temp >= 0 && temp < 1000 && _selector != -1 && scene._bgShapes[temp]._aType == PERSON) { // Giving an object to a person + width1 = screen.stringWidth(inv[_selector]._name); x = width = screen.stringWidth("Give "); x += width1; width2 = screen.stringWidth(" to "); @@ -1235,13 +1237,12 @@ void UserInterface::doInvControl() { if (found != -1) // If a slot highlighted, set it's color colors[found] = COMMAND_HIGHLIGHTED; - screen.buttonPrint(Common::Point(INVENTORY_POINTS[0][2], CONTROLS_Y1), - colors[0], true, "Exit"); + screen.buttonPrint(Common::Point(INVENTORY_POINTS[0][2], CONTROLS_Y1), colors[0], true, "Exit"); if (found >= 0 && found <= 3) { screen.buttonPrint(Common::Point(INVENTORY_POINTS[1][2], CONTROLS_Y1), colors[1], true, "Look"); - screen.buttonPrint(Common::Point(INVENTORY_POINTS[2][2], CONTROLS_Y1), colors[1], true, "Use"); - screen.buttonPrint(Common::Point(INVENTORY_POINTS[3][2], CONTROLS_Y1), colors[1], true, "Give"); + screen.buttonPrint(Common::Point(INVENTORY_POINTS[2][2], CONTROLS_Y1), colors[2], true, "Use"); + screen.buttonPrint(Common::Point(INVENTORY_POINTS[3][2], CONTROLS_Y1), colors[3], true, "Give"); inv._invMode = (InvMode)found; _selector = -1; } -- cgit v1.2.3 From 3a8aa6956812d8e69c6b5e1021ba5c05e3fe0b0b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 26 Apr 2015 23:31:29 -0500 Subject: SHERLOCK: Fixes for using flower on lab table --- engines/sherlock/scene.cpp | 4 ++++ engines/sherlock/talk.cpp | 3 ++- engines/sherlock/user_interface.cpp | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 7c31788a2f..7b885a2cb9 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -953,6 +953,8 @@ int Scene::startCAnim(int cAnimNum, int playRate) { cObj._imageFrame = &(*cObj._images)[0]; cObj._maxFrames = cObj._images->size(); + ++_ongoingCans; + int frames = 0; if (playRate < 0) { // Reverse direction @@ -1362,6 +1364,8 @@ void Scene::doBgAnim() { screen.slamArea(o._position.x, o._position.y, o._delta.x, o._delta.y); _canimShapes.remove_at(idx); + if (_ongoingCans > 0) + --_ongoingCans; } else if (o._type == ACTIVE_BG_SHAPE) { screen.flushImage(o._imageFrame, o._position, &o._oldPosition.x, &o._oldPosition.y, &o._oldSize.x, &o._oldSize.y); diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 94779ae760..ea2cb16252 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -312,7 +312,8 @@ void Talk::talkTo(const Common::String &filename) { select = _talkIndex = idx; } - if (_scriptMoreFlag && _scriptSelect != 0) + // If there's a pending automatic selection to be made, then use it + if (_scriptMoreFlag && _scriptSelect != 100) select = _scriptSelect; if (select == -1) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 97f6cfd63a..e4d7255774 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -818,7 +818,7 @@ void UserInterface::lookScreen(const Common::Point &pt) { tempStr.deleteLastChar(); } - int xStart = (SHERLOCK_SCREEN_HEIGHT - x) / 2; + int xStart = (SHERLOCK_SCREEN_WIDTH - x) / 2; screen.print(Common::Point(xStart, INFO_LINE + 1), INFO_FOREGROUND, "Use "); -- cgit v1.2.3 From 80fba27cb372c052a912e23595fcd201fd688acf Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 27 Apr 2015 02:18:57 -0500 Subject: SHERLOCK: Fix analysing flower on lab table --- engines/sherlock/scene.cpp | 3 +++ engines/sherlock/talk.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 7b885a2cb9..f6fe8c8671 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -1014,6 +1014,9 @@ int Scene::startCAnim(int cAnimNum, int playRate) { while (--temp > 0) { cObj._frameNumber--; doBgAnim(); + + if (_vm->shouldQuit()) + return 0; } cObj._frameNumber += dir; diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index ea2cb16252..427be09cc3 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1117,7 +1117,7 @@ void Talk::doScript(const Common::String &script) { // doing bg anims in the next call, so we need to know where to return to ++str; _scriptCurrentIndex = (str + 1) - script.c_str(); - scene.startCAnim(((byte)str[0] - 1) & 127, 1 + ((byte)str[0] & 128)); + scene.startCAnim(((byte)str[0] - 1) & 127, ((byte)str[0] & 128) ? -1 : 1); if (_talkToAbort) return; -- cgit v1.2.3 From a2e1f4cb76a6629f53a7f03c8b9bc2efa5f701e6 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 27 Apr 2015 02:29:34 -0500 Subject: SHERLOCK: Fix using items within the scene --- engines/sherlock/user_interface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index e4d7255774..b12094638c 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1422,7 +1422,7 @@ void UserInterface::doInvControl() { checkUseAction(&scene._bgShapes[_find]._use[0], inv[_selector]._name, MUSE, _find, temp - 2); else // Now inv object has been highlighted - checkUseAction(&scene._bgShapes[_find]._use[0], "*SELF", MUSE, _find, temp - 2); + checkUseAction(&scene._bgShapes[_find]._use[0], "*SELF*", MUSE, _find, temp - 2); _selector = _oldSelector = -1; } -- cgit v1.2.3 From f7f405eadb355089b17bb7d146b0e06da04f27e2 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 27 Apr 2015 04:40:19 -0500 Subject: SHERLOCK: Further fixes for analysing flower on lab table --- engines/sherlock/talk.cpp | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 427be09cc3..29bfff8674 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -134,7 +134,7 @@ Talk::Talk(SherlockEngine *vm): _vm(vm) { _talkStealth = 0; _talkToFlag = -1; _moreTalkDown = _moreTalkUp = false; - _scriptMoreFlag = false; + _scriptMoreFlag = 0; _scriptSaveIndex = -1; _scriptCurrentIndex = -1; } @@ -217,7 +217,7 @@ void Talk::talkTo(const Common::String &filename) { } } - while (!_scriptStack.empty()) + while (!_sequenceStack.empty()) pullSequence(); // Restore any pressed button @@ -578,6 +578,9 @@ void Talk::loadTalkFile(const Common::String &filename) { Resources &res = *_vm->_res; Sound &sound = *_vm->_sound; + // Save a copy of the talk filename + _scriptName = filename; + // Check for an existing person being talked to _talkTo = -1; for (int idx = 0; idx < MAX_PEOPLE; ++idx) { @@ -867,7 +870,7 @@ int Talk::talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt * Clears the stack of pending object sequences associated with speakers in the scene */ void Talk::clearSequences() { - _scriptStack.clear(); + _sequenceStack.clear(); } /** @@ -1385,7 +1388,7 @@ void Talk::doScript(const Common::String &script) { case ADD_ITEM_TO_INVENTORY: ++str; for (int idx = 0; idx < str[0]; ++idx) - tempString += str[idx]; + tempString += str[idx + 1]; str += str[0]; inv.putNameInInventory(tempString); @@ -1420,16 +1423,24 @@ void Talk::doScript(const Common::String &script) { _scriptCurrentIndex = str - script.c_str(); // Save the current script position and new talk file - if (_scriptStack.size() < 10) { - ScriptStackEntry rec; - rec._name = _scriptName; - rec._currentIndex = _scriptCurrentIndex; - rec._select = _scriptSelect; + if (_scriptStack.size() < 9) { + ScriptStackEntry rec1; + rec1._name = _scriptName; + rec1._currentIndex = _scriptCurrentIndex; + rec1._select = _scriptSelect; + _scriptStack.push(rec1); + + // Push the new talk file onto the stack + ScriptStackEntry rec2; + rec2._name = tempString; + rec2._currentIndex = 0; + rec2._select = 100; + _scriptStack.push(rec2); } else { error("Script stack overflow"); } - _scriptMoreFlag = true; + _scriptMoreFlag = 1; endStr = true; wait = 0; break; @@ -1655,7 +1666,7 @@ void Talk::doScript(const Common::String &script) { } pullSequence(); - if (_speaker < 128) + if (_speaker >= 0 && _speaker < 128) people.clearTalking(); } } @@ -1749,7 +1760,7 @@ void Talk::popStack() { _scriptName = scriptEntry._name; _scriptSaveIndex = scriptEntry._currentIndex; _scriptSelect = scriptEntry._select; - _scriptMoreFlag = true; + _scriptMoreFlag = 1; } } -- cgit v1.2.3 From 7be410621e9fbc61ff4ec715044afaa79aa54717 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 27 Apr 2015 04:51:16 -0500 Subject: SHERLOCK: Fixes for giving flower to Wiggins --- engines/sherlock/talk.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 29bfff8674..ed09ddde9c 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -365,8 +365,9 @@ void Talk::talkTo(const Common::String &filename) { // Check for a linked file if (!statement._linkFile.empty() && !_scriptMoreFlag) { + Common::String linkFilename = statement._linkFile; freeTalkVars(); - loadTalkFile(statement._linkFile); + loadTalkFile(linkFilename); // Scan for the first valid statement in the newly loaded file select = -1; @@ -427,7 +428,7 @@ void Talk::talkTo(const Common::String &filename) { } else { // Add the statement into the journal and talk history if (_talkTo != -1 && !_talkHistory[_converseNum][select]) - journal.record(_converseNum | 2048, select); + journal.record(_converseNum, select, true); _talkHistory[_converseNum][select] = true; } -- cgit v1.2.3 From 34a7ec7cdfe6b2eae699968afa28f2f75ee3126c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 28 Apr 2015 21:35:20 -1000 Subject: SHERLOCK: Fix icon disappearing when moving to Covent Gradens on map Co-ordinates in Sherlock are frequently multiplied by 100. Thus, on the overland map, the values can go up to 64000, which overflows the signed 16-bit values allowed by the standard Common::Point class --- engines/sherlock/map.h | 6 +++--- engines/sherlock/objects.cpp | 2 +- engines/sherlock/objects.h | 23 +++++++++++++++++++++-- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/engines/sherlock/map.h b/engines/sherlock/map.h index 564ae73691..435ca8d5d7 100644 --- a/engines/sherlock/map.h +++ b/engines/sherlock/map.h @@ -68,7 +68,7 @@ private: ImageFile *_shapes; ImageFile *_iconShapes; byte _sequences[MAX_HOLMES_SEQUENCE][MAX_FRAME]; - Common::Point _lDrawnPos; + Point32 _lDrawnPos; int _point; bool _placesShown; int _cursorIndex; @@ -96,8 +96,8 @@ private: void highlightIcon(const Common::Point &pt); public: bool _active; - Common::Point _overPos; - Common::Point _bigPos; + Point32 _overPos; + Point32 _bigPos; int _charPoint, _oldCharPoint; public: Map(SherlockEngine *vm); diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index f662d00aed..d9cc38e55f 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -184,7 +184,7 @@ void Sprite::checkSprite() { Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; Talk &talk = *_vm->_talk; - Common::Point pt; + Point32 pt; Common::Rect objBounds; Common::Point spritePt(_position.x / 100, _position.y / 100); diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 80b0b9d9f3..e2b53ec541 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -79,6 +79,25 @@ enum { #define FLIP_CODE (64 + 128) #define SOUND_CODE (34 + 128) +class Point32 { +public: + int x; + int y; + + Point32() : x(0), y(0) {} + Point32(int x1, int y1) : x(x1), y(y1) {} + Point32(const Common::Point &pt) : x(pt.x), y(pt.y) {} + + bool operator==(const Point32 &p) const { return x == p.x && y == p.y; } + bool operator!=(const Point32 &p) const { return x != p.x || y != p.y; } + Point32 operator+(const Point32 &delta) const { return Point32(x + delta.x, y + delta.y); } + Point32 operator-(const Point32 &delta) const { return Point32(x - delta.x, y - delta.y); } + operator Common::Point() { return Common::Point(x, y); } + + void operator+=(const Point32 &delta) { x += delta.x; y += delta.y; } + void operator-=(const Point32 &delta) { x -= delta.x; y -= delta.y; } +}; + class Sprite { private: static SherlockEngine *_vm; @@ -95,8 +114,8 @@ public: int _allow; // Allowed menu commands - ObjectAllow int _frameNumber; // Frame number in rame sequence to draw int _sequenceNumber; // Sequence being used - Common::Point _position; // Current position - Common::Point _delta; // Momvement delta + Point32 _position; // Current position + Point32 _delta; // Momvement delta Common::Point _oldPosition; // Old position Common::Point _oldSize; // Image's old size Common::Point _goto; // Walk destination -- cgit v1.2.3 From 4b53d6a54b121e20d6bd4bfb6f1851b120817101 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 29 Apr 2015 18:02:08 -1000 Subject: SHERLOCK: Fixes for darts minigame --- engines/sherlock/events.cpp | 1 + engines/sherlock/scalpel/darts.cpp | 76 +++++++++++++++++++++--------------- engines/sherlock/scalpel/darts.h | 4 +- engines/sherlock/scalpel/scalpel.cpp | 2 +- 4 files changed, 49 insertions(+), 34 deletions(-) diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index f83219d7d2..f7cbdd301e 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -214,6 +214,7 @@ Common::KeyState Events::getKey() { */ void Events::clearEvents() { _pendingKeys.clear(); + _mouseButtons = 0; _pressed = _released = false; _rightPressed = _rightReleased = false; _oldButtons = _oldRightButton = false; diff --git a/engines/sherlock/scalpel/darts.cpp b/engines/sherlock/scalpel/darts.cpp index c3f2c478d7..0f3c36420e 100644 --- a/engines/sherlock/scalpel/darts.cpp +++ b/engines/sherlock/scalpel/darts.cpp @@ -60,7 +60,7 @@ Darts::Darts(ScalpelEngine *vm) : _vm(vm) { _roundNumber = 0; _playerDartMode = false; _roundScore = 0; - _oldDartButtons = 0; + _oldDartButtons = false; } /** @@ -75,7 +75,7 @@ void Darts::playDarts() { // Change the font int oldFont = screen.fontNumber(); - screen.setFont(4); + screen.setFont(2); loadDarts(); initDarts(); @@ -89,6 +89,9 @@ void Darts::playDarts() { showStatus(playerNumber); _roundScore = 0; + if (_vm->shouldQuit()) + return; + for (int idx = 0; idx < 3; ++idx) { // Throw a single dart if (_computerPlayer == 1) @@ -165,7 +168,7 @@ void Darts::playDarts() { done |= _vm->shouldQuit(); if (!done) { - screen._backBuffer2.blitFrom((*_dartImages)[1], Common::Point(0, 0)); + screen._backBuffer2.blitFrom((*_dartImages)[0], Common::Point(0, 0)); screen._backBuffer1.blitFrom(screen._backBuffer2); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } @@ -185,7 +188,9 @@ void Darts::loadDarts() { Screen &screen = *_vm->_screen; _dartImages = new ImageFile("darts.vgs"); - screen._backBuffer1.blitFrom((*_dartImages)[1], Common::Point(0, 0)); + screen.setPalette(_dartImages->_palette); + + screen._backBuffer1.blitFrom((*_dartImages)[0], Common::Point(0, 0)); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } @@ -223,7 +228,7 @@ void Darts::closeDarts() { } /** - * Show the player names + * Show the names of the people playing, Holmes and his opponent */ void Darts::showNames(int playerNum) { Screen &screen = *_vm->_screen; @@ -243,14 +248,14 @@ void Darts::showNames(int playerNum) { color = playerNum == 1 ? PLAYER_COLOR : DART_COL_FORE; if (playerNum != 0) - screen.print(Common::Point(STATUS_INFO_X + 50, STATUS_INFO_Y + 10), PLAYER_COLOR + 3, + screen.print(Common::Point(STATUS_INFO_X + 50, STATUS_INFO_Y), PLAYER_COLOR + 3, _opponent.c_str()); else - screen.print(Common::Point(STATUS_INFO_X + 50, STATUS_INFO_Y + 10), color, + screen.print(Common::Point(STATUS_INFO_X + 50, STATUS_INFO_Y), color, _opponent.c_str()); screen._backBuffer1.fillRect(Common::Rect(STATUS_INFO_X + 50, STATUS_INFO_Y + 10, - STATUS_INFO_Y + 81, STATUS_INFO_Y + 12), color); + STATUS_INFO_X + 81, STATUS_INFO_Y + 12), color); screen.slamArea(STATUS_INFO_X + 50, STATUS_INFO_Y + 10, 81, 12); // Make a copy of the back buffer to the secondary one @@ -264,8 +269,9 @@ void Darts::showStatus(int playerNum) { Screen &screen = *_vm->_screen; byte color; + // Copy scoring screen from secondary back buffer. This will erase any previously displayed status/score info screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 10), - Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10, SHERLOCK_SCREEN_WIDTH, STATUS_INFO_Y + 38)); + Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10, SHERLOCK_SCREEN_WIDTH, STATUS_INFO_Y + 48)); color = (playerNum == 0) ? PLAYER_COLOR : DART_COL_FORE; screen.print(Common::Point(STATUS_INFO_X + 6, STATUS_INFO_Y + 13), color, "%d", _dartScore1); @@ -306,6 +312,9 @@ int Darts::throwDart(int dartNum, int computer) { events.delay(10); } + if (_vm->shouldQuit()) + return 0; + screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(DART_INFO_X, DART_INFO_Y - 1), Common::Rect(DART_INFO_X, DART_INFO_Y - 1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); screen.slamRect(Common::Rect(DART_INFO_X, DART_INFO_Y - 1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); @@ -319,15 +328,16 @@ int Darts::throwDart(int dartNum, int computer) { // For human players, slight y adjustment if (computer == 0) - height = 2; + height += 2; - // Copy the bars to the secondary back buffer + // Copy the bars to the secondary back buffer so that they remain fixed at their selected values + // whilst the dart is being animated at being thrown at the board screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(DARTBARHX - 1, DARTHORIZY - 1), Common::Rect(DARTBARHX - 1, DARTHORIZY - 1, DARTBARHX + DARTBARSIZE + 3, DARTHORIZY + 10)); screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(DARTBARVX - 1, DARTHEIGHTY - 1), Common::Rect(DARTBARVX - 1, DARTHEIGHTY - 1, DARTBARVX + 11, DARTHEIGHTY + DARTBARSIZE + 3)); - // Convert to relative range from -49 to 150 + // Convert height and width to relative range of -50 to 50, where 0,0 is the exact centre of the board height -= 50; width -= 50; @@ -347,13 +357,13 @@ void Darts::drawDartThrow(const Common::Point &pt) { Common::Rect oldDrawBounds; int delta = 9; - for (int idx = 5; idx < 24; ++idx) { + for (int idx = 4; idx < 23; ++idx) { Graphics::Surface &frame = (*_dartImages)[idx]._frame; // Adjust draw position for animating dart - if (idx < 14) + if (idx < 13) pos.y -= delta--; - else if (idx == 14) + else if (idx == 13) delta = 1; else pos.y += delta++; @@ -363,20 +373,19 @@ void Darts::drawDartThrow(const Common::Point &pt) { screen._backBuffer1.transBlitFrom(frame, drawPos); screen.slamArea(drawPos.x, drawPos.y, frame.w, frame.h); - // Handle erasing old dart + // Handle erasing old dart strs if (!oldDrawBounds.isEmpty()) screen.slamRect(oldDrawBounds); oldDrawBounds = Common::Rect(drawPos.x, drawPos.y, drawPos.x + frame.w, drawPos.y + frame.h); - if (idx != 23) - screen._backBuffer1.blitFrom(screen._backBuffer2, drawPos, oldDrawBounds); + screen._backBuffer1.blitFrom(screen._backBuffer2, drawPos, oldDrawBounds); events.wait(2); } // Draw dart in final "stuck to board" form - screen._backBuffer1.transBlitFrom((*_dartImages)[23], Common::Point(oldDrawBounds.left, oldDrawBounds.top)); - screen._backBuffer2.transBlitFrom((*_dartImages)[23], Common::Point(oldDrawBounds.left, oldDrawBounds.top)); + screen._backBuffer1.transBlitFrom((*_dartImages)[22], Common::Point(oldDrawBounds.left, oldDrawBounds.top)); + screen._backBuffer2.transBlitFrom((*_dartImages)[22], Common::Point(oldDrawBounds.left, oldDrawBounds.top)); screen.slamRect(oldDrawBounds); } @@ -388,8 +397,8 @@ void Darts::erasePowerBars() { screen._backBuffer1.fillRect(Common::Rect(DARTBARHX, DARTHORIZY, DARTBARHX + DARTBARSIZE, DARTHORIZY + 10), 0); screen._backBuffer1.fillRect(Common::Rect(DARTBARVX, DARTHEIGHTY, DARTBARVX + 10, DARTHEIGHTY + DARTBARSIZE), 0); - screen._backBuffer1.transBlitFrom((*_dartImages)[3], Common::Point(DARTBARHX - 1, DARTHORIZY - 1)); - screen._backBuffer1.transBlitFrom((*_dartImages)[4], Common::Point(DARTBARVX - 1, DARTHEIGHTY - 1)); + screen._backBuffer1.transBlitFrom((*_dartImages)[2], Common::Point(DARTBARHX - 1, DARTHORIZY - 1)); + screen._backBuffer1.transBlitFrom((*_dartImages)[3], Common::Point(DARTBARVX - 1, DARTHEIGHTY - 1)); screen.slamArea(DARTBARHX - 1, DARTHORIZY - 1, DARTBARSIZE + 3, 11); screen.slamArea(DARTBARVX - 1, DARTHEIGHTY - 1, 11, DARTBARSIZE + 3); } @@ -427,11 +436,11 @@ int Darts::doPowerBar(const Common::Point &pt, byte color, int goToPower, bool i if (isVertical) { screen._backBuffer1.hLine(pt.x, pt.y + DARTBARSIZE - 1 - idx, pt.x + 8, color); - screen._backBuffer1.transBlitFrom((*_dartImages)[4], Common::Point(pt.x - 1, pt.y - 1)); + screen._backBuffer1.transBlitFrom((*_dartImages)[3], Common::Point(pt.x - 1, pt.y - 1)); screen.slamArea(pt.x, pt.y + DARTBARSIZE - 1 - idx, 8, 2); } else { screen._backBuffer1.vLine(pt.x + idx, pt.y, pt.y + 8, color); - screen._backBuffer1.transBlitFrom((*_dartImages)[3], Common::Point(pt.x - 1, pt.y - 1)); + screen._backBuffer1.transBlitFrom((*_dartImages)[2], Common::Point(pt.x - 1, pt.y - 1)); screen.slamArea(pt.x + idx, pt.y, 1, 8); } @@ -452,18 +461,23 @@ int Darts::doPowerBar(const Common::Point &pt, byte color, int goToPower, bool i /** * Returns true if a mouse button or key is pressed. */ -int Darts::dartHit() { +bool Darts::dartHit() { Events &events = *_vm->_events; - if (events.kbHit()) { - Common::KeyState keyState = events.getKey(); + // Process pending events + events.pollEventsAndWait(); + if (events.kbHit()) { + // Key was pressed, so discard it and return true events.clearKeyboard(); - return keyState.keycode; + return true; } + _oldDartButtons = events._pressed; events.setButtonState(); - return events._pressed && !_oldDartButtons ? 1 : 0; + + // Only return true if the mouse button is newly pressed + return (events._pressed && !_oldDartButtons) ? 1 : 0; } /** @@ -477,7 +491,7 @@ int Darts::dartScore(const Common::Point &pt) { return 0; // On board, so get the score from the pixel at that position - int score = *(const byte *)(*_dartImages)[2]._frame.getBasePtr(pos.x, pos.y); + int score = *(const byte *)(*_dartImages)[1]._frame.getBasePtr(pos.x, pos.y); return score; } @@ -545,7 +559,7 @@ Common::Point Darts::getComputerDartDest(int playerNum) { * Returns the center position for the area of the dartboard with a given number */ bool Darts::findNumberOnBoard(int aim, Common::Point &pt) { - ImageFrame &board = (*_dartImages)[2]; + ImageFrame &board = (*_dartImages)[1]; // Scan board image for the special "center" pixels bool done = false; diff --git a/engines/sherlock/scalpel/darts.h b/engines/sherlock/scalpel/darts.h index a6c8cdba6d..50be572067 100644 --- a/engines/sherlock/scalpel/darts.h +++ b/engines/sherlock/scalpel/darts.h @@ -42,7 +42,7 @@ private: Common::String _opponent; bool _playerDartMode; int _roundScore; - int _oldDartButtons; + bool _oldDartButtons; void loadDarts(); void initDarts(); @@ -57,7 +57,7 @@ private: void erasePowerBars(); int doPowerBar(const Common::Point &pt, byte color, int goToPower, bool isVertical); - int dartHit(); + bool dartHit(); int dartScore(const Common::Point &pt); Common::Point getComputerDartDest(int playerNum); diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 89e042d382..627a8b7b7f 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -614,7 +614,7 @@ void ScalpelEngine::startScene() { _events->setCursor(ARROW); if (_scene->_goToScene == 99) { - // Chess Board + // Darts Board minigame _darts->playDarts(); _mapResult = _scene->_goToScene = 19; // Go back to the bar } -- cgit v1.2.3 From 0ef0b4570a861d117c27b5f72af991506814820c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 29 Apr 2015 18:11:35 -1000 Subject: SHERLOCK: Minor bugfix and cleanup for dartScore --- engines/sherlock/scalpel/darts.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/scalpel/darts.cpp b/engines/sherlock/scalpel/darts.cpp index 0f3c36420e..476a3071c5 100644 --- a/engines/sherlock/scalpel/darts.cpp +++ b/engines/sherlock/scalpel/darts.cpp @@ -485,13 +485,14 @@ bool Darts::dartHit() { */ int Darts::dartScore(const Common::Point &pt) { Common::Point pos(pt.x - 37, pt.y - 33); + Graphics::Surface &scoreImg = (*_dartImages)[1]._frame; - if (pos.x < 0 || pos.y < 0 || pos.x >= 147 || pt.y >= 132) + if (pos.x < 0 || pos.y < 0 || pos.x >= scoreImg.w || pos.y >= scoreImg.h) // Not on the board return 0; // On board, so get the score from the pixel at that position - int score = *(const byte *)(*_dartImages)[1]._frame.getBasePtr(pos.x, pos.y); + int score = *(const byte *)scoreImg.getBasePtr(pos.x, pos.y); return score; } -- cgit v1.2.3 From e3881ccbb90cb7e650ba1e7d47e6c7dfe5133fdd Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 29 Apr 2015 21:12:56 -1000 Subject: SHERLOCK: Fix display of place names on overhead map --- engines/sherlock/map.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index b0cf246e52..a807d52f91 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -355,7 +355,8 @@ void Map::saveTopLine() { */ void Map::eraseTopLine() { Screen &screen = *_vm->_screen; - screen.blitFrom(_topLine, Common::Point(0, 0)); + screen._backBuffer1.blitFrom(_topLine, Common::Point(0, 0)); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, _topLine.h); } /** -- cgit v1.2.3 From ef4ec4cde3ec15d7370ef739e4fa6d863e7ccee5 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 29 Apr 2015 21:24:34 -1000 Subject: SHERLOCK: Fix moving crates in Tabacco Shop --- engines/sherlock/user_interface.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index b12094638c..b0b0d15b5c 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -2592,16 +2592,22 @@ void UserInterface::checkAction(ActionType &action, const char *const messages[] cAnimNum = 9; else cAnimNum = action._cAnimNum - 1; - CAnim &anim = scene._cAnim[cAnimNum]; - + if (action._cAnimNum != 99) { - if (action._cAnimSpeed & REVERSE_DIRECTION) { - pt = anim._teleportPos; - dir = anim._teleportDir; - } else { - pt = anim._goto; - dir = anim._gotoDir; + CAnim &anim = scene._cAnim[cAnimNum]; + + if (action._cAnimNum != 99) { + if (action._cAnimSpeed & REVERSE_DIRECTION) { + pt = anim._teleportPos; + dir = anim._teleportDir; + } else { + pt = anim._goto; + dir = anim._gotoDir; + } } + } else { + pt = Common::Point(-1, -1); + dir = -1; } if (action._cAnimSpeed) { -- cgit v1.2.3 From f34b9a59b52460cae64d526cf9d9eccba922e376 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 29 Apr 2015 21:38:06 -1000 Subject: SHERLOCK: Fix Sherlock gliding when walking vertically --- engines/sherlock/people.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 2eff1a0973..ed6e0607bd 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -386,7 +386,9 @@ void People::setWalking() { // If we're on the overhead map, set the sequence so we keep moving // in the same direction - _player._sequenceNumber = (oldDirection == -1) ? MAP_RIGHT : oldDirection; + if (map._active) { + _player._sequenceNumber = (oldDirection == -1) ? MAP_RIGHT : oldDirection; + } // Set the delta x _player._delta.x = (delta.x * 100) / (delta.y / speed.y); -- cgit v1.2.3 From aba28c4737d8534d160ed0ada17c6c109c0e7b4c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 29 Apr 2015 21:41:49 -1000 Subject: SHERLOCK: Move _slowChess to Map _frameChangeFlag --- engines/sherlock/map.cpp | 1 + engines/sherlock/map.h | 1 + engines/sherlock/objects.cpp | 2 +- engines/sherlock/sherlock.cpp | 1 - engines/sherlock/sherlock.h | 1 - 5 files changed, 3 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index a807d52f91..5ff27a9709 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -64,6 +64,7 @@ Map::Map(SherlockEngine *vm): _vm(vm), _topLine(SHERLOCK_SCREEN_WIDTH, 12) { _overPos = Common::Point(13000, 12600); _charPoint = 0; _oldCharPoint = 39; + _frameChangeFlag = false; for (int idx = 0; idx < MAX_HOLMES_SEQUENCE; ++idx) Common::fill(&_sequences[idx][0], &_sequences[idx][MAX_FRAME], 0); diff --git a/engines/sherlock/map.h b/engines/sherlock/map.h index 435ca8d5d7..e4c6655db9 100644 --- a/engines/sherlock/map.h +++ b/engines/sherlock/map.h @@ -99,6 +99,7 @@ public: Point32 _overPos; Point32 _bigPos; int _charPoint, _oldCharPoint; + bool _frameChangeFlag; public: Map(SherlockEngine *vm); diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index d9cc38e55f..04c7599b6d 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -126,7 +126,7 @@ void Sprite::adjustSprite() { _position.x = CLIP((int)_position.x, LEFT_LIMIT, RIGHT_LIMIT); } - if (!map._active || (_vm->_slowChess = !_vm->_slowChess)) + if (!map._active || (map._frameChangeFlag = !map._frameChangeFlag)) ++_frameNumber; if ((*_sequences)[_sequenceNumber][_frameNumber] == 0) { diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 406b796fc9..a8d3d9a535 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -47,7 +47,6 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _ui = nullptr; _useEpilogue2 = false; _loadingSavedGame = false; - _slowChess = false; _keyPadSpeed = 0; _loadGameSlot = -1; _canLoadSave = false; diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 921559183d..3f0779421c 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -104,7 +104,6 @@ public: Common::String _titleOverride; bool _useEpilogue2; bool _loadingSavedGame; - bool _slowChess; int _keyPadSpeed; int _loadGameSlot; bool _canLoadSave; -- cgit v1.2.3 From 21d17357540d3a45522684467d2259dca7cf20db Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 29 Apr 2015 22:12:59 -1000 Subject: SHERLOCK: Fix script byte casting in journal loading --- engines/sherlock/journal.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 255662f71c..b9669d209e 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -240,7 +240,7 @@ int Journal::loadJournalFile(bool alreadyLoaded) { const char *replyP = statement._reply.c_str(); while (*replyP) { - byte c = *replyP++; + byte c = (byte)*replyP++; // Is it a control character? if (c < 128) { @@ -289,7 +289,7 @@ int Journal::loadJournalFile(bool alreadyLoaded) { const char *strP = replyP + 1; char v; do { - v = *strP++; + v = (byte)*strP++; } while (v && v < 128 && v != '.' && v != '!' && v != '?'); if (v == '?') @@ -334,9 +334,9 @@ int Journal::loadJournalFile(bool alreadyLoaded) { journalString += NAMES[c]; const char *strP = replyP; - char v; + byte v; do { - v = *strP++; + v = (byte)*strP++; } while (v && v < 128 && v != '.' && v != '!' && v != '?'); if (v == '?') @@ -356,7 +356,7 @@ int Journal::loadJournalFile(bool alreadyLoaded) { break; case 134: // Change sequence - replyP += (replyP[0] & 127) + replyP[2] + 2; + replyP += ((byte)replyP[0] & 127) + (byte)replyP[2] + 2; break; case 135: // Walk to co-ords @@ -380,7 +380,7 @@ int Journal::loadJournalFile(bool alreadyLoaded) { case 152: // Set object case 155: // Info line case 158: // Delete item from inventory - replyP += (*replyP & 127) + 1; + replyP += ((byte)*replyP & 127) + 1; break; case 149: // Goto scene -- cgit v1.2.3 From 6d32c570d0f4ac956059a450581d46ce0d75ad97 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 29 Apr 2015 22:56:07 -1000 Subject: SHERLOCK: Fix journal loading change sequence opcode --- engines/sherlock/journal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index b9669d209e..c30b4683d9 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -356,7 +356,7 @@ int Journal::loadJournalFile(bool alreadyLoaded) { break; case 134: // Change sequence - replyP += ((byte)replyP[0] & 127) + (byte)replyP[2] + 2; + replyP += ((byte)replyP[0] & 127) + (byte)replyP[1] + 2; break; case 135: // Walk to co-ords -- cgit v1.2.3 From 7ca3b75805eb404ad7f5ae01ba3000593e8eaf36 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 29 Apr 2015 23:17:51 -1000 Subject: SHERLOCK: Fix clicking in script zones starting the script --- engines/sherlock/objects.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 04c7599b6d..f353844774 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -924,6 +924,8 @@ void Object::setFlagsAndToggles() { if (_use[useIdx]._cAnimSpeed) { if (_use[useIdx]._cAnimNum == 0) // 0 is really a 10 + scene.startCAnim(9, _use[useIdx]._cAnimSpeed); + else scene.startCAnim(_use[useIdx]._cAnimNum - 1, _use[useIdx]._cAnimSpeed); } -- cgit v1.2.3 From 56f43eff10a038a67954cd4ccc6990bb70fa6740 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 30 Apr 2015 10:24:18 -1000 Subject: SHERLOCK: Fix loading scenes with initially hidden objects --- engines/sherlock/scene.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index f6fe8c8671..1d00e9d23d 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -414,6 +414,9 @@ bool Scene::loadScene(const Common::String &filename) { if (_bgShapes[idx]._type != HIDDEN && (_bgShapes[idx]._flags & 0x40) && _bgShapes[idx]._type != INVALID) _bgShapes[idx].toggleHidden(); + if (_bgShapes[idx]._type == HIDE_SHAPE) + // Hiding isn't needed, since objects aren't drawn yet + _bgShapes[idx]._type = HIDDEN; } } -- cgit v1.2.3 From 00fd812028c6aaa9b2ec05963a66a23dabbd33ba Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 30 Apr 2015 11:23:31 -1000 Subject: SHERLOCK: Properly restrict scene drawing to scene area --- engines/sherlock/graphics.cpp | 8 ------- engines/sherlock/graphics.h | 2 -- engines/sherlock/map.cpp | 1 - engines/sherlock/scene.cpp | 53 ++++++++++++++++++++++--------------------- engines/sherlock/screen.cpp | 26 ++++++++++++++++++--- engines/sherlock/screen.h | 1 + 6 files changed, 51 insertions(+), 40 deletions(-) diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index 6e986c839b..6fd046e458 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -164,14 +164,6 @@ void Surface::fillRect(const Common::Rect &r, byte color) { addDirtyRect(r); } -/** - * Return a sub-area of the surface as a new surface object. The surfaces - * are shared in common, so changes in the sub-surface affects the original. - */ -Surface Surface::getSubArea(const Common::Rect &r) { - return Surface(*this, r); -} - /** * Clips the given source bounds so the passed destBounds will be entirely on-screen */ diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index 85f3ba8c40..80b692130c 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -55,8 +55,6 @@ public: void fillRect(int x1, int y1, int x2, int y2, byte color); void fillRect(const Common::Rect &r, byte color); - - Surface getSubArea(const Common::Rect &r); }; } // End of namespace Sherlock diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index 5ff27a9709..f572e3771a 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -442,7 +442,6 @@ void Map::updateMap(bool flushScreen) { */ void Map::walkTheStreets() { People &people = *_vm->_people; - Scene &scene = *_vm->_scene; bool reversePath = false; Common::Array tempPath; diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 1d00e9d23d..50e62b7ba5 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -716,10 +716,11 @@ int Scene::toggleObject(const Common::String &name) { void Scene::updateBackground() { People &people = *_vm->_people; Screen &screen = *_vm->_screen; - Surface surface = screen._backBuffer1.getSubArea( - Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); Sprite &player = people[AL]; + // Restrict drawing window + screen.setDisplayBounds(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); + // Update Holmes if he's turned on if (people._holmesOn) player.adjustSprite(); @@ -731,26 +732,26 @@ void Scene::updateBackground() { // Draw all active shapes which are behind the person for (uint idx = 0; idx < _bgShapes.size(); ++idx) { if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE && _bgShapes[idx]._misc == BEHIND) - surface.transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); + screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); } // Draw all canimations which are behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if (_canimShapes[idx]._type == ACTIVE_BG_SHAPE && _canimShapes[idx]._misc == BEHIND) - surface.transBlitFrom(*_canimShapes[idx]._imageFrame, + screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, _canimShapes[idx]._flags & 2); } // Draw all active shapes which are normal and behind the person for (uint idx = 0; idx < _bgShapes.size(); ++idx) { if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE && _bgShapes[idx]._misc == NORMAL_BEHIND) - surface.transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); + screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); } // Draw all canimations which are normal and behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if (_canimShapes[idx]._type == ACTIVE_BG_SHAPE && _canimShapes[idx]._misc == NORMAL_BEHIND) - surface.transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, + screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, _canimShapes[idx]._flags & 2); } @@ -760,7 +761,7 @@ void Scene::updateBackground() { player._sequenceNumber == WALK_UPLEFT || player._sequenceNumber == STOP_UPLEFT || player._sequenceNumber == WALK_DOWNRIGHT || player._sequenceNumber == STOP_DOWNRIGHT; - surface.transBlitFrom(*player._imageFrame, Common::Point(player._position.x / 100, + screen._backBuffer->transBlitFrom(*player._imageFrame, Common::Point(player._position.x / 100, player._position.y / 100 - player.frameHeight()), flipped); } @@ -768,14 +769,14 @@ void Scene::updateBackground() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { if ((_bgShapes[idx]._type == ACTIVE_BG_SHAPE || _bgShapes[idx]._type == STATIC_BG_SHAPE) && _bgShapes[idx]._misc == NORMAL_FORWARD) - surface.transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); + screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); } // Draw all static and active canimations that are NORMAL and are in front of the player for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if ((_canimShapes[idx]._type == ACTIVE_BG_SHAPE || _canimShapes[idx]._type == STATIC_BG_SHAPE) && _canimShapes[idx]._misc == NORMAL_FORWARD) - surface.transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, + screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, _canimShapes[idx]._flags & 2); } @@ -787,14 +788,14 @@ void Scene::updateBackground() { if ((_bgShapes[idx]._type == ACTIVE_BG_SHAPE || _bgShapes[idx]._type == STATIC_BG_SHAPE) && _bgShapes[idx]._misc == FORWARD) - surface.transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); + screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); } // Draw all static and active canimations that are forward for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if ((_canimShapes[idx]._type == ACTIVE_BG_SHAPE || _canimShapes[idx]._type == STATIC_BG_SHAPE) && _canimShapes[idx]._misc == FORWARD) - surface.transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, + screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, _canimShapes[idx]._flags & 2); } } @@ -1079,8 +1080,8 @@ void Scene::doBgAnim() { Sound &sound = *_vm->_sound; Talk &talk = *_vm->_talk; UserInterface &ui = *_vm->_ui; - Surface surface = screen._backBuffer1.getSubArea(Common::Rect(0, 0, - SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); + + screen.setDisplayBounds(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); int cursorId = events.getCursor(); Common::Point mousePos = events.mousePos(); @@ -1150,7 +1151,7 @@ void Scene::doBgAnim() { if (people[AL]._type == CHARACTER) screen.restoreBackground(bounds); else if (people[AL]._type == REMOVE) - screen._backBuffer1.blitFrom(screen._backBuffer2, pt, bounds); + screen._backBuffer->blitFrom(screen._backBuffer2, pt, bounds); for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; @@ -1169,7 +1170,7 @@ void Scene::doBgAnim() { Object &o = _bgShapes[idx]; if (o._type == NO_SHAPE && ((o._flags & 1) == 0)) { // Restore screen area - screen._backBuffer1.blitFrom(screen._backBuffer2, o._position, + screen._backBuffer->blitFrom(screen._backBuffer2, o._position, Common::Rect(o._position.x, o._position.y, o._position.x + o._noShapeSize.x, o._position.y + o._noShapeSize.y)); @@ -1218,14 +1219,14 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == BEHIND) - screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } // Draw all canimations which are behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == BEHIND) { - screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } } @@ -1233,14 +1234,14 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == NORMAL_BEHIND) - screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } // Draw all canimations which are NORMAL and behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == NORMAL_BEHIND) { - screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } } @@ -1253,7 +1254,7 @@ void Scene::doBgAnim() { bool flipped = people[AL]._sequenceNumber == WALK_LEFT || people[AL]._sequenceNumber == STOP_LEFT || people[AL]._sequenceNumber == WALK_UPLEFT || people[AL]._sequenceNumber == STOP_UPLEFT || people[AL]._sequenceNumber == WALK_DOWNRIGHT || people[AL]._sequenceNumber == STOP_DOWNRIGHT; - screen._backBuffer1.transBlitFrom(*people[AL]._imageFrame, + screen._backBuffer->transBlitFrom(*people[AL]._imageFrame, Common::Point(tempX, people[AL]._position.y / 100 - people[AL]._imageFrame->_frame.h), flipped); } @@ -1261,14 +1262,14 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == NORMAL_FORWARD) - screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } // Draw all static and active canimations that are NORMAL and are in front of the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == NORMAL_BEHIND) { - screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } } @@ -1276,19 +1277,19 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == FORWARD) - screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } // Draw any active portrait if (people._portraitLoaded && people._portrait._type == ACTIVE_BG_SHAPE) - screen._backBuffer1.transBlitFrom(*people._portrait._imageFrame, + screen._backBuffer->transBlitFrom(*people._portrait._imageFrame, people._portrait._position, people._portrait._flags & 2); // Draw all static and active canimations that are in front of the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == FORWARD) { - screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } } @@ -1296,7 +1297,7 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if (o._type == NO_SHAPE && (o._flags & 1) == 0) - screen._backBuffer1.transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } // Bring the newly built picture to the screen diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 3c9a10e4a1..66590c3ada 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -39,6 +39,10 @@ Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCR Common::fill(&_cMap[0], &_cMap[PALETTE_SIZE], 0); Common::fill(&_sMap[0], &_sMap[PALETTE_SIZE], 0); setFont(1); + + // Set dummy surface used for restricted scene drawing + _sceneSurface.format = Graphics::PixelFormat::createFormatCLUT8(); + _sceneSurface.pitch = SHERLOCK_SCREEN_WIDTH; } Screen::~Screen() { @@ -469,15 +473,31 @@ void Screen::makePanel(const Common::Rect &r) { _backBuffer->hLine(r.left + 1, r.bottom - 2, r.right - 1, BUTTON_BOTTOM); } +/** + * Sets the active back buffer pointer to a restricted sub-area of the first back buffer + */ void Screen::setDisplayBounds(const Common::Rect &r) { - // TODO: See if needed + assert(r.left == 0 && r.top == 0); + _sceneSurface.setPixels(_backBuffer1.getPixels()); + _sceneSurface.w = r.width(); + _sceneSurface.h = r.height(); + + _backBuffer = &_sceneSurface; } + +/** + * Resets the active buffer pointer to point back to the full first back buffer + */ void Screen::resetDisplayBounds() { - setDisplayBounds(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + _backBuffer = &_backBuffer1; } +/** + * Return the size of the current display window + */ Common::Rect Screen::getDisplayBounds() { - return Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + return (_backBuffer == &_sceneSurface) ? Common::Rect(0, 0, _sceneSurface.w, _sceneSurface.h) : + Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } /** diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index a8bdc53b5a..bbfba1c575 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -65,6 +65,7 @@ private: uint32 _transitionSeed; ImageFile *_font; int _fontHeight; + Surface _sceneSurface; void mergeDirtyRects(); -- cgit v1.2.3 From 50da2a2dd8ff6be1f634bd6d9f2b8d54bf059b9d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 30 Apr 2015 12:21:11 -1000 Subject: SHERLOCK: Fix display of item descriptions --- engines/sherlock/scene.cpp | 4 ++++ engines/sherlock/talk.cpp | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 50e62b7ba5..487688f3a5 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -798,6 +798,8 @@ void Scene::updateBackground() { screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, _canimShapes[idx]._flags & 2); } + + screen.resetDisplayBounds(); } Exit *Scene::checkForExit(const Common::Rect &r) { @@ -1082,6 +1084,7 @@ void Scene::doBgAnim() { UserInterface &ui = *_vm->_ui; screen.setDisplayBounds(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); + int cursorId = events.getCursor(); Common::Point mousePos = events.mousePos(); @@ -1384,6 +1387,7 @@ void Scene::doBgAnim() { events.wait(1); _doBgAnimDone = true; + screen.resetDisplayBounds(); // Check if the method was called for calling a portrait, and a talk was // interrupting it. This talk file would not have been executed at the time, diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index ed09ddde9c..b4dde2e6b0 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -455,7 +455,11 @@ void Talk::talkTo(const Common::String &filename) { events._pressed = events._released = events._oldButtons = 0; events.clearKeyboard(); - screen.setDisplayBounds(savedBounds); + if (savedBounds.bottom == SHERLOCK_SCREEN_HEIGHT) + screen.resetDisplayBounds(); + else + screen.setDisplayBounds(savedBounds); + _talkToAbort = abortFlag; // If a script was added to the script stack, restore state so that the -- cgit v1.2.3 From 329f6d744cf1aa002f013be0e5b0af62873598e2 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 30 Apr 2015 12:51:46 -1000 Subject: SHERLOCK: Fix DISPLAY_INFO_LINE talk opcode --- engines/sherlock/talk.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index b4dde2e6b0..7686df2944 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1468,6 +1468,7 @@ void Talk::doScript(const Common::String &script) { str += str[0]; screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, tempString.c_str()); + ui._menuCounter = 30; break; case CLEAR_INFO_LINE: -- cgit v1.2.3 From d57cb94752c8c833c06bc1ef531f53587ab1df55 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 30 Apr 2015 15:01:15 -1000 Subject: SHERLOCK: Fix picking up pail at docks --- engines/sherlock/talk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 7686df2944..5a36303b21 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1403,7 +1403,7 @@ void Talk::doScript(const Common::String &script) { ++str; for (int idx = 0; idx < (str[0] & 127); ++idx) tempString += str[idx + 1]; - str += str[0]; + str += str[0] & 127; // Set comparison state according to if we want to hide or unhide bool state = ((byte)str[0] >= 128); -- cgit v1.2.3 From c4008703d1c20afac1ce60a37fc85b9cd2bba0f8 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 30 Apr 2015 15:04:08 -1000 Subject: SHERLOCK: More descriptive comment for talkTo --- engines/sherlock/talk.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 5a36303b21..de99fe0e88 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -149,9 +149,12 @@ void Talk::setSequences(const byte *talkSequences, const byte *stillSequences, i } /** - * Called when either an NPC initiates a conversation or for inventory item - * descriptions. It opens up a description window similar to how 'talk' does, - * but shows a 'reply' directly instead of waiting for a statement option. + * Called whenever a conversation or item script needs to be run. For standard conversations, + * it opens up a description window similar to how 'talk' does, but shows a 'reply' directly + * instead of waiting for a statement option. + * @remarks It seems that at some point, all item scripts were set up to use this as well. + * In their case, the conversation display is simply suppressed, and control is passed on to + * doScript to implement whatever action is required. */ void Talk::talkTo(const Common::String &filename) { Events &events = *_vm->_events; -- cgit v1.2.3 From 862d63c2a6c8b55bd472809508ba119ca41397dd Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 30 Apr 2015 15:20:48 -1000 Subject: SHERLOCK: Partial fix for Blackwell capture cutscene --- engines/sherlock/animation.cpp | 4 ++-- engines/sherlock/scalpel/scalpel.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 4674151ec7..810c0ecc34 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -90,7 +90,7 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f else if (_vm->_useEpilogue2) stream = _vm->_res->load(vdxName, "epilog2.lib"); else - stream = _vm->_res->load(vdxName, "epilogoue.lib"); + stream = _vm->_res->load(vdxName, "epilogue.lib"); // Load initial image Common::String vdaName = baseName + ".vda"; @@ -127,7 +127,7 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f } // Draw the sprite - screen.transBlitFrom(images[imageFrame]._frame, pt); + screen.transBlitFrom(images[imageFrame], pt); } else { // No sprite to show for this animation frame if (fade == 255) { diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 627a8b7b7f..488a4de772 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -505,7 +505,7 @@ void ScalpelEngine::startScene() { _res->addToCache("final2.vda", "epilogue.lib"); _res->addToCache("final2.vdx", "epilogue.lib"); _animation->playPrologue("final1", 1, 3, true, 4); - _animation->playPrologue("final22", 1, 0, false, 4); + _animation->playPrologue("final2", 1, 0, false, 4); break; case 52: -- cgit v1.2.3 From e25fbfa8e4a2e6ca2ef187630479151107f8ff19 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 30 Apr 2015 15:38:13 -1000 Subject: SHERLOCK: Fix initial entry conversation with coroner at morgue --- engines/sherlock/objects.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index f353844774..3dc50e61b1 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -200,12 +200,12 @@ void Sprite::checkSprite() { if (obj._type == NO_SHAPE) { objBounds = Common::Rect(obj._position.x, obj._position.y, - obj._position.x + obj._noShapeSize.x, obj._position.y + obj._noShapeSize.y); + obj._position.x + obj._noShapeSize.x + 1, obj._position.y + obj._noShapeSize.y + 1); } else { int xp = obj._position.x + obj._imageFrame->_offset.x; int yp = obj._position.y + obj._imageFrame->_offset.y; objBounds = Common::Rect(xp, yp, - xp + obj._imageFrame->_frame.w, yp + obj._imageFrame->_frame.h); + xp + obj._imageFrame->_frame.w + 1, yp + obj._imageFrame->_frame.h + 1); } if (objBounds.contains(pt)) { -- cgit v1.2.3 From 8e4ccdbd2c5ea543d648ef46300837c3c43ee705 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 30 Apr 2015 15:46:30 -1000 Subject: SHERLOCK: Fix trying to move items that can't be --- engines/sherlock/user_interface.cpp | 59 +++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index b0b0d15b5c..30d79aa1c9 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -2585,32 +2585,42 @@ void UserInterface::checkAction(ActionType &action, const char *const messages[] if (objNum >= 1000) // Ignore actions done on characters return; - Object &obj = scene._bgShapes[objNum]; - if (action._cAnimNum == 0) - // Really a 10 - cAnimNum = 9; - else - cAnimNum = action._cAnimNum - 1; - - if (action._cAnimNum != 99) { - CAnim &anim = scene._cAnim[cAnimNum]; + if (!action._cAnimSpeed) { + // Invalid action, to print error message + _infoFlag = true; + clearInfo(); + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, messages[action._cAnimNum]); + _infoFlag = true; + + // Set how long to show the message + _menuCounter = 30; + } else { + Object &obj = scene._bgShapes[objNum]; + if (action._cAnimNum == 0) + // Really a 10 + cAnimNum = 9; + else + cAnimNum = action._cAnimNum - 1; + if (action._cAnimNum != 99) { - if (action._cAnimSpeed & REVERSE_DIRECTION) { - pt = anim._teleportPos; - dir = anim._teleportDir; - } else { - pt = anim._goto; - dir = anim._gotoDir; + CAnim &anim = scene._cAnim[cAnimNum]; + + if (action._cAnimNum != 99) { + if (action._cAnimSpeed & REVERSE_DIRECTION) { + pt = anim._teleportPos; + dir = anim._teleportDir; + } else { + pt = anim._goto; + dir = anim._gotoDir; + } } + } else { + pt = Common::Point(-1, -1); + dir = -1; } - } else { - pt = Common::Point(-1, -1); - dir = -1; - } - if (action._cAnimSpeed) { // Has a value, so do action // Show wait cursor whilst walking to object and doing action events.setCursor(WAIT); @@ -2686,15 +2696,6 @@ void UserInterface::checkAction(ActionType &action, const char *const messages[] _menuCounter = 30; } } - } else { - // Invalid action, to print error message - _infoFlag = true; - clearInfo(); - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, messages[action._cAnimNum]); - _infoFlag = true; - - // Set how long to show the message - _menuCounter = 30; } // Reset cursor back to arrow -- cgit v1.2.3 From e37cf9c4d0d33c0b0ba9eb7bb842b49205baac4b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 30 Apr 2015 16:00:08 -1000 Subject: SHERLOCK: Fix talking to Gregson at morgue --- engines/sherlock/talk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index de99fe0e88..3320beb30c 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -524,7 +524,7 @@ void Talk::talk(int objNum) { obj._lookFacing); events.setCursor(ARROW); - if (_talkToAbort) + if (!_talkToAbort) talkTo(obj._name); } else { // Holmes will be speaking first -- cgit v1.2.3 From e332565119b7efe85ba91fd601f994997912481f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 30 Apr 2015 16:59:36 -1000 Subject: SHERLOCK: Fix Gregson disappearing at Morgue --- engines/sherlock/talk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 3320beb30c..eb5c763106 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1406,10 +1406,10 @@ void Talk::doScript(const Common::String &script) { ++str; for (int idx = 0; idx < (str[0] & 127); ++idx) tempString += str[idx + 1]; - str += str[0] & 127; // Set comparison state according to if we want to hide or unhide bool state = ((byte)str[0] >= 128); + str += str[0] & 127; for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) { Object &obj = scene._bgShapes[idx]; -- cgit v1.2.3 From 2bc1d2badc79ba2d49ebc225731d602938f7d49e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 30 Apr 2015 17:55:58 -1000 Subject: SHERLOCK: Fix showing corpse portraits in Morgue --- engines/sherlock/scene.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 487688f3a5..3cc84936b0 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -1271,7 +1271,7 @@ void Scene::doBgAnim() { // Draw all static and active canimations that are NORMAL and are in front of the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; - if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == NORMAL_BEHIND) { + if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == NORMAL_FORWARD) { screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } } -- cgit v1.2.3 From d811e4a9ff48426b01f199db8f24b00e679592d5 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 30 Apr 2015 20:44:19 -1000 Subject: SHERLOCK: Fix color of talk response text --- engines/sherlock/talk.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index eb5c763106..2c59876e84 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1573,9 +1573,9 @@ void Talk::doScript(const Common::String &script) { // If the speaker indicates a description file, print it in yellow if (_speaker != -1) { if (ui._windowOpen) { - screen.print(Common::Point(16, yp), INV_FOREGROUND, lineStr.c_str()); + screen.print(Common::Point(16, yp), COMMAND_FOREGROUND, lineStr.c_str()); } else { - screen.gPrint(Common::Point(16, yp - 1), INV_FOREGROUND, lineStr.c_str()); + screen.gPrint(Common::Point(16, yp - 1), COMMAND_FOREGROUND, lineStr.c_str()); openTalkWindow = true; } } else { -- cgit v1.2.3 From 821040deaaa4dabf160795e96cb223ba192a87d3 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 30 Apr 2015 21:00:48 -1000 Subject: SHERLOCK: Fix blank talk windows sometimes remaining open --- engines/sherlock/talk.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 2c59876e84..ed8092c03e 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1159,7 +1159,7 @@ void Talk::doScript(const Common::String &script) { case PAUSE: // Pause - charCount = *++str; + charCount = (byte)*++str; wait = pauseFlag = true; break; @@ -1598,8 +1598,8 @@ void Talk::doScript(const Common::String &script) { ++line; // Certain different conditions require a wait - if ((line == 4 && str[0] != SFX_COMMAND && str[0] != PAUSE && _speaker != -1) || - (line == 5 && str[0] != PAUSE && _speaker != -1) || + if ((line == 4 && (byte)str[0] != SFX_COMMAND && (byte)str[0] != PAUSE && _speaker != -1) || + (line == 5 && (byte)str[0] != PAUSE && _speaker != -1) || endStr) { wait = 1; } -- cgit v1.2.3 From 56f8d54e5133ecdc6e6cceda27202bf6ba7e26fd Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 30 Apr 2015 21:07:33 -1000 Subject: SHERLOCK: Use script opcode constants in journal loading --- engines/sherlock/journal.cpp | 40 ++++++++++++++++++++-------------------- engines/sherlock/talk.cpp | 41 +---------------------------------------- engines/sherlock/talk.h | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 60 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index c30b4683d9..be76756bdd 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -346,48 +346,48 @@ int Journal::loadJournalFile(bool alreadyLoaded) { } else { // Control code, so move past it and any parameters switch (c) { - case 129: // Run canim - case 130: // Assign side - case 131: // Pause with control - case 136: // Pause without control - case 157: // Walk to canimation + case RUN_CANIMATION: + case ASSIGN_PORTRAIT_LOCATION: + case PAUSE: + case PAUSE_WITHOUT_CONTROL: + case WALK_TO_CANIMATION: // These commands have a single parameter ++replyP; break; - case 134: // Change sequence + case ADJUST_OBJ_SEQUENCE: replyP += ((byte)replyP[0] & 127) + (byte)replyP[1] + 2; break; - case 135: // Walk to co-ords - case 154: // Move mouse + case WALK_TO_COORDS: + case MOVE_MOUSE: replyP += 4; break; - case 139: // Set flag - case 143: // If statement + case SET_FLAG: + case IF_STATEMENT: replyP += 2; break; - case 140: // Play voice file - case 150: // Play prologue - case 153: // Call talk file + case SFX_COMMAND: + case PLAY_PROLOGUE: + case CALL_TALK_FILE: replyP += 8; break; - case 141: // Toggle object - case 151: // Put item in inventory - case 152: // Set object - case 155: // Info line - case 158: // Delete item from inventory + case TOGGLE_OBJECT: + case ADD_ITEM_TO_INVENTORY: + case SET_OBJECT: + case DISPLAY_INFO_LINE: + case REMOVE_ITEM_FROM_INVENTORY: replyP += ((byte)*replyP & 127) + 1; break; - case 149: // Goto scene + case GOTO_SCENE: replyP += 5; break; - case 161: // End of line + case CARRIAGE_RETURN: journalString += "\n"; break; diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index ed8092c03e..fb16995d2b 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -26,45 +26,6 @@ namespace Sherlock { -enum { - SWITCH_SPEAKER = 128, - RUN_CANIMATION = 129, - ASSIGN_PORTRAIT_LOCATION = 130, - PAUSE = 131, - REMOVE_PORTRAIT = 132, - CLEAR_WINDOW = 133, - ADJUST_OBJ_SEQUENCE = 134, - WALK_TO_COORDS = 135, - PAUSE_WITHOUT_CONTROL = 136, - BANISH_WINDOW = 137, - SUMMON_WINDOW = 138, - SET_FLAG = 139, - SFX_COMMAND = 140, - TOGGLE_OBJECT = 141, - STEALTH_MODE_ACTIVE = 142, - IF_STATEMENT = 143, - ELSE_STATEMENT = 144, - END_IF_STATEMENT = 145, - STEALTH_MODE_DEACTIVATE = 146, - TURN_HOLMES_OFF = 147, - TURN_HOLMES_ON = 148, - GOTO_SCENE = 149, - PLAY_PROLOGUE = 150, - ADD_ITEM_TO_INVENTORY = 151, - SET_OBJECT = 152, - CALL_TALK_FILE = 153, - MOVE_MOUSE = 154, - DISPLAY_INFO_LINE = 155, - CLEAR_INFO_LINE = 156, - WALK_TO_CANIMATION = 157, - REMOVE_ITEM_FROM_INVENTORY = 158, - ENABLE_END_KEY = 159, - DISABLE_END_KEY = 160, - COMMAND_161 = 161 -}; - -/*----------------------------------------------------------------*/ - /** * Load the data for a single statement within a talk file */ @@ -1621,7 +1582,7 @@ void Talk::doScript(const Common::String &script) { } // Open window if it wasn't already open, and text has already been printed - if ((openTalkWindow && wait) || (openTalkWindow && (byte)str[0] >= 128 && (byte)str[0] != COMMAND_161)) { + if ((openTalkWindow && wait) || (openTalkWindow && (byte)str[0] >= 128 && (byte)str[0] != CARRIAGE_RETURN)) { if (!ui._windowStyle) { screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); } else { diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index 620a986454..d545d31351 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -35,6 +35,43 @@ namespace Sherlock { #define MAX_TALK_SEQUENCES 11 #define MAX_TALK_FILES 500 +enum { + SWITCH_SPEAKER = 128, + RUN_CANIMATION = 129, + ASSIGN_PORTRAIT_LOCATION = 130, + PAUSE = 131, + REMOVE_PORTRAIT = 132, + CLEAR_WINDOW = 133, + ADJUST_OBJ_SEQUENCE = 134, + WALK_TO_COORDS = 135, + PAUSE_WITHOUT_CONTROL = 136, + BANISH_WINDOW = 137, + SUMMON_WINDOW = 138, + SET_FLAG = 139, + SFX_COMMAND = 140, + TOGGLE_OBJECT = 141, + STEALTH_MODE_ACTIVE = 142, + IF_STATEMENT = 143, + ELSE_STATEMENT = 144, + END_IF_STATEMENT = 145, + STEALTH_MODE_DEACTIVATE = 146, + TURN_HOLMES_OFF = 147, + TURN_HOLMES_ON = 148, + GOTO_SCENE = 149, + PLAY_PROLOGUE = 150, + ADD_ITEM_TO_INVENTORY = 151, + SET_OBJECT = 152, + CALL_TALK_FILE = 153, + MOVE_MOUSE = 154, + DISPLAY_INFO_LINE = 155, + CLEAR_INFO_LINE = 156, + WALK_TO_CANIMATION = 157, + REMOVE_ITEM_FROM_INVENTORY = 158, + ENABLE_END_KEY = 159, + DISABLE_END_KEY = 160, + CARRIAGE_RETURN = 161 +}; + struct SequenceEntry { int _objNum; Common::Array _sequences; -- cgit v1.2.3 From 9117083e0ab8f329a93bcae647d9da78ec212738 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 30 Apr 2015 21:21:59 -1000 Subject: SHERLOCK: Fix crash in Equestrian shop --- engines/sherlock/user_interface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 30d79aa1c9..e7e7981966 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -414,8 +414,8 @@ void UserInterface::handleInput() { _infoFlag = true; clearInfo(); - if (_help != -1 && (scene._bgShapes[_bgFound]._description[0] != 32 && - scene._bgShapes[_bgFound]._description[0])) + if (_help != -1 && !scene._bgShapes[_bgFound]._description.empty() + && scene._bgShapes[_bgFound]._description[0] != ' ') screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, scene._bgShapes[_bgFound]._description.c_str()); -- cgit v1.2.3 From d32eb9a70f5c44b16d1262f5d0d62a09d8e893d3 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 30 Apr 2015 21:31:18 -1000 Subject: SHERLOCK: Simplify all the castings of char to byte in Talk and Journal --- engines/sherlock/journal.cpp | 18 +++++----- engines/sherlock/talk.cpp | 78 +++++++++++++++++++++++--------------------- 2 files changed, 49 insertions(+), 47 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index be76756bdd..67cff15218 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -237,10 +237,10 @@ int Journal::loadJournalFile(bool alreadyLoaded) { bool ctrlSpace = false; bool commentFlag = false; bool commentJustPrinted = false; - const char *replyP = statement._reply.c_str(); + const byte *replyP = (const byte *)statement._reply.c_str(); while (*replyP) { - byte c = (byte)*replyP++; + byte c = *replyP++; // Is it a control character? if (c < 128) { @@ -286,10 +286,10 @@ int Journal::loadJournalFile(bool alreadyLoaded) { else journalString += NAMES[talk._talkTo]; - const char *strP = replyP + 1; + const byte *strP = replyP + 1; char v; do { - v = (byte)*strP++; + v = *strP++; } while (v && v < 128 && v != '.' && v != '!' && v != '?'); if (v == '?') @@ -306,7 +306,7 @@ int Journal::loadJournalFile(bool alreadyLoaded) { journalString += c; do { journalString += *replyP++; - } while (*replyP && (byte)*replyP < 128 && *replyP != '{' && *replyP != '}'); + } while (*replyP && *replyP < 128 && *replyP != '{' && *replyP != '}'); commentJustPrinted = false; } @@ -333,10 +333,10 @@ int Journal::loadJournalFile(bool alreadyLoaded) { else journalString += NAMES[c]; - const char *strP = replyP; + const byte *strP = replyP; byte v; do { - v = (byte)*strP++; + v = *strP++; } while (v && v < 128 && v != '.' && v != '!' && v != '?'); if (v == '?') @@ -356,7 +356,7 @@ int Journal::loadJournalFile(bool alreadyLoaded) { break; case ADJUST_OBJ_SEQUENCE: - replyP += ((byte)replyP[0] & 127) + (byte)replyP[1] + 2; + replyP += (replyP[0] & 127) + replyP[1] + 2; break; case WALK_TO_COORDS: @@ -380,7 +380,7 @@ int Journal::loadJournalFile(bool alreadyLoaded) { case SET_OBJECT: case DISPLAY_INFO_LINE: case REMOVE_ITEM_FROM_INVENTORY: - replyP += ((byte)*replyP & 127) + 1; + replyP += (*replyP & 127) + 1; break; case GOTO_SCENE: diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index fb16995d2b..9e75f4ecc8 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -993,14 +993,16 @@ void Talk::doScript(const Common::String &script) { _saveSeqNum = 0; - const char *str = script.c_str(); + const byte *scriptStart = (const byte *)script.c_str(); + const byte *str = scriptStart; + if (_scriptMoreFlag) { _scriptMoreFlag = 0; - str = script.c_str() + _scriptSaveIndex; + str = scriptStart + _scriptSaveIndex; } // Check if the script begins with a Stealh Mode Active command - if ((byte)str[0] == STEALTH_MODE_ACTIVE || _talkStealth) { + if (str[0] == STEALTH_MODE_ACTIVE || _talkStealth) { _talkStealth = 2; _speaker |= 128; } else { @@ -1008,7 +1010,7 @@ void Talk::doScript(const Common::String &script) { ui.clearWindow(); // Need to switch speakers? - if ((byte)str[0] == SWITCH_SPEAKER) { + if (str[0] == SWITCH_SPEAKER) { _speaker = str[1] - 1; str += 2; pullSequence(); @@ -1019,7 +1021,7 @@ void Talk::doScript(const Common::String &script) { } // Assign portrait location? - if ((byte)str[0] == ASSIGN_PORTRAIT_LOCATION) { + if (str[0] == ASSIGN_PORTRAIT_LOCATION) { switch (str[1] & 15) { case 1: people._portraitSide = 20; @@ -1041,7 +1043,7 @@ void Talk::doScript(const Common::String &script) { } // Remove portrait? - if ((byte)str[0] == REMOVE_PORTRAIT) { + if (str[0] == REMOVE_PORTRAIT) { _speaker = 255; } else { // Nope, so set the first speaker @@ -1053,7 +1055,7 @@ void Talk::doScript(const Common::String &script) { Common::String tempString; wait = 0; - byte c = (byte)str[0]; + byte c = str[0]; if (!c) { endStr = true; } else if (c == '{') { @@ -1066,7 +1068,7 @@ void Talk::doScript(const Common::String &script) { case SWITCH_SPEAKER: // Save the current point in the script, since it might be intterupted by // doing bg anims in the next call, so we need to know where to return to - _scriptCurrentIndex = str - script.c_str(); + _scriptCurrentIndex = str - scriptStart; if (!(_speaker & 128)) people.clearTalking(); @@ -1088,13 +1090,13 @@ void Talk::doScript(const Common::String &script) { // Save the current point in the script, since it might be intterupted by // doing bg anims in the next call, so we need to know where to return to ++str; - _scriptCurrentIndex = (str + 1) - script.c_str(); - scene.startCAnim(((byte)str[0] - 1) & 127, ((byte)str[0] & 128) ? -1 : 1); + _scriptCurrentIndex = (str + 1) - scriptStart; + scene.startCAnim((str[0] - 1) & 127, (str[0] & 128) ? -1 : 1); if (_talkToAbort) return; // Check if next character is changing side or changing portrait - if (charCount && ((byte)str[1] == SWITCH_SPEAKER || (byte)str[1] == ASSIGN_PORTRAIT_LOCATION)) + if (charCount && (str[1] == SWITCH_SPEAKER || str[1] == ASSIGN_PORTRAIT_LOCATION)) wait = 1; break; @@ -1120,14 +1122,14 @@ void Talk::doScript(const Common::String &script) { case PAUSE: // Pause - charCount = (byte)*++str; + charCount = *++str; wait = pauseFlag = true; break; case REMOVE_PORTRAIT: // Save the current point in the script, since it might be intterupted by // doing bg anims in the next call, so we need to know where to return to - _scriptCurrentIndex = str - script.c_str(); + _scriptCurrentIndex = str - scriptStart; if (_speaker >= 0 && _speaker < 128) people.clearTalking(); @@ -1186,10 +1188,10 @@ void Talk::doScript(const Common::String &script) { // Save the current point in the script, since it might be intterupted by // doing bg anims in the next call, so we need to know where to return to ++str; - _scriptCurrentIndex = str - script.c_str(); + _scriptCurrentIndex = str - scriptStart; - people.walkToCoords(Common::Point((((byte)str[0] - 1) * 256 + (byte)str[1] - 1) * 100, - (byte)str[2] * 100), str[3] - 1); + people.walkToCoords(Common::Point(((str[0] - 1) * 256 + str[1] - 1) * 100, + str[2] * 100), str[3] - 1); if (_talkToAbort) return; @@ -1200,7 +1202,7 @@ void Talk::doScript(const Common::String &script) { // Save the current point in the script, since it might be intterupted by // doing bg anims in the next call, so we need to know where to return to ++str; - _scriptCurrentIndex = str - script.c_str(); + _scriptCurrentIndex = str - scriptStart; for (int idx = 0; idx < (str[0] - 1); ++idx) { scene.doBgAnim(); @@ -1216,7 +1218,7 @@ void Talk::doScript(const Common::String &script) { case BANISH_WINDOW: // Save the current point in the script, since it might be intterupted by // doing bg anims in the next call, so we need to know where to return to - _scriptCurrentIndex = str - script.c_str(); + _scriptCurrentIndex = str - scriptStart; if (!(_speaker & 128)) people.clearTalking(); @@ -1246,7 +1248,7 @@ void Talk::doScript(const Common::String &script) { case SET_FLAG: { ++str; - int flag1 = ((byte)str[0] - 1) * 256 + (byte)str[1] - 1 - (str[1] == 1 ? 1 : 0); + int flag1 = (str[0] - 1) * 256 + str[1] - 1 - (str[1] == 1 ? 1 : 0); int flag = (flag1 & 0x3fff) * (flag1 >= 0x4000 ? -1 : 1); _vm->setFlags(flag); ++str; @@ -1284,7 +1286,7 @@ void Talk::doScript(const Common::String &script) { case IF_STATEMENT: { ++str; - int flag = ((byte)str[0] - 1) * 256 + (byte)str[1] - 1 - (str[1] == 1 ? 1 : 0); + int flag = (str[0] - 1) * 256 + str[1] - 1 - (str[1] == 1 ? 1 : 0); ++str; wait = 0; @@ -1334,14 +1336,14 @@ void Talk::doScript(const Common::String &script) { // Run a canimation? if (str[2] > 100) { - people._hSavedFacing = (byte)str[2]; + people._hSavedFacing = str[2]; people._hSavedPos = Common::Point(160, 100); } } str += 6; _scriptMoreFlag = (scene._goToScene == 100) ? 2 : 1; - _scriptSaveIndex = str - script.c_str(); + _scriptSaveIndex = str - scriptStart; endStr = true; wait = 0; break; @@ -1369,7 +1371,7 @@ void Talk::doScript(const Common::String &script) { tempString += str[idx + 1]; // Set comparison state according to if we want to hide or unhide - bool state = ((byte)str[0] >= 128); + bool state = (str[0] >= 128); str += str[0] & 127; for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) { @@ -1389,7 +1391,7 @@ void Talk::doScript(const Common::String &script) { tempString += str[idx]; str += 8; - _scriptCurrentIndex = str - script.c_str(); + _scriptCurrentIndex = str - scriptStart; // Save the current script position and new talk file if (_scriptStack.size() < 9) { @@ -1418,8 +1420,8 @@ void Talk::doScript(const Common::String &script) { // Save the current point in the script, since it might be intterupted by // doing bg anims in the next call, so we need to know where to return to ++str; - _scriptCurrentIndex = str - script.c_str(); - events.moveMouse(Common::Point(((byte)str[0] - 1) * 256 + (byte)str[1] - 1, str[2])); + _scriptCurrentIndex = str - scriptStart; + events.moveMouse(Common::Point((str[0] - 1) * 256 + str[1] - 1, str[2])); if (_talkToAbort) return; str += 3; @@ -1446,7 +1448,7 @@ void Talk::doScript(const Common::String &script) { // Save the current point in the script, since it might be intterupted by // doing bg anims in the next call, so we need to know where to return to - _scriptCurrentIndex = (str + 1) - script.c_str(); + _scriptCurrentIndex = (str + 1) - scriptStart; people.walkToCoords(anim._goto, anim._gotoDir); if (_talkToAbort) @@ -1509,10 +1511,10 @@ void Talk::doScript(const Common::String &script) { width += screen.charWidth(str[idx]); ++idx; ++charCount; - } while (width < 298 && str[idx] && str[idx] != '{' && (byte)str[idx] < 128); + } while (width < 298 && str[idx] && str[idx] != '{' && str[idx] < 128); if (str[idx] || width >= 298) { - if ((byte)str[idx] < 128 && str[idx] != '{') { + if (str[idx] < 128 && str[idx] != '{') { --idx; --charCount; } @@ -1529,7 +1531,7 @@ void Talk::doScript(const Common::String &script) { } // Print the line - Common::String lineStr(str, str + idx); + Common::String lineStr((const char *)str, (const char *)str + idx); // If the speaker indicates a description file, print it in yellow if (_speaker != -1) { @@ -1552,20 +1554,20 @@ void Talk::doScript(const Common::String &script) { str += idx; // If line wrap occurred, then move to after the separating space between the words - if ((byte)str[0] < 128 && str[0] != '{') + if (str[0] < 128 && str[0] != '{') ++str; yp += 9; ++line; // Certain different conditions require a wait - if ((line == 4 && (byte)str[0] != SFX_COMMAND && (byte)str[0] != PAUSE && _speaker != -1) || - (line == 5 && (byte)str[0] != PAUSE && _speaker != -1) || + if ((line == 4 && str[0] != SFX_COMMAND && str[0] != PAUSE && _speaker != -1) || + (line == 5 && str[0] != PAUSE && _speaker != -1) || endStr) { wait = 1; } - switch ((byte)str[0]) { + switch (str[0]) { case SWITCH_SPEAKER: case ASSIGN_PORTRAIT_LOCATION: case BANISH_WINDOW: @@ -1582,7 +1584,7 @@ void Talk::doScript(const Common::String &script) { } // Open window if it wasn't already open, and text has already been printed - if ((openTalkWindow && wait) || (openTalkWindow && (byte)str[0] >= 128 && (byte)str[0] != CARRIAGE_RETURN)) { + if ((openTalkWindow && wait) || (openTalkWindow && str[0] >= 128 && str[0] != CARRIAGE_RETURN)) { if (!ui._windowStyle) { screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); } else { @@ -1596,7 +1598,7 @@ void Talk::doScript(const Common::String &script) { if (wait) { // Save the current point in the script, since it might be intterupted by // doing bg anims in the next call, so we need to know where to return to - _scriptCurrentIndex = str - script.c_str(); + _scriptCurrentIndex = str - scriptStart; // Handling pausing if (!pauseFlag && charCount < 160) @@ -1608,12 +1610,12 @@ void Talk::doScript(const Common::String &script) { // If a key was pressed to finish the window, see if further voice files should be skipped if (wait >= 0 && wait < 254) { - if ((byte)str[0] == SFX_COMMAND) + if (str[0] == SFX_COMMAND) str += 9; } // Clear the window unless the wait was due to a PAUSE command - if (!pauseFlag && wait != -1 && (byte)str[0] != SFX_COMMAND) { + if (!pauseFlag && wait != -1 && str[0] != SFX_COMMAND) { if (!_talkStealth) ui.clearWindow(); yp = CONTROLS_Y + 12; -- cgit v1.2.3 From 9d99f1ebe726785beb0b3053b3cdc60a0fd64894 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 30 Apr 2015 21:46:12 -1000 Subject: SHERLOCK: Fix looking at items with multiple pages of description --- engines/sherlock/talk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 9e75f4ecc8..da72125f72 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1562,7 +1562,7 @@ void Talk::doScript(const Common::String &script) { // Certain different conditions require a wait if ((line == 4 && str[0] != SFX_COMMAND && str[0] != PAUSE && _speaker != -1) || - (line == 5 && str[0] != PAUSE && _speaker != -1) || + (line == 5 && str[0] != PAUSE && _speaker == -1) || endStr) { wait = 1; } -- cgit v1.2.3 From 24a36d610685b2024e864138224cc61e09f4ae16 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 30 Apr 2015 22:11:29 -1000 Subject: SHERLOCK: Fix crash loading scene 42, which didn't have any canimations --- engines/sherlock/scene.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 3cc84936b0..ec7831820a 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -295,16 +295,19 @@ bool Scene::loadScene(const Common::String &filename) { } // Load in cAnim list - Common::SeekableReadStream *canimStream = _lzwMode ? - decompressLZ(*rrmStream, 65 * bgHeader._numcAnimations) : - rrmStream->readStream(65 * bgHeader._numcAnimations); + _cAnim.clear(); + if (bgHeader._numcAnimations) { + Common::SeekableReadStream *canimStream = _lzwMode ? + decompressLZ(*rrmStream, 65 * bgHeader._numcAnimations) : + rrmStream->readStream(65 * bgHeader._numcAnimations); - _cAnim.resize(bgHeader._numcAnimations); - for (uint idx = 0; idx < _cAnim.size(); ++idx) - _cAnim[idx].synchronize(*canimStream); + _cAnim.resize(bgHeader._numcAnimations); + for (uint idx = 0; idx < _cAnim.size(); ++idx) + _cAnim[idx].synchronize(*canimStream); + + delete canimStream; + } - delete canimStream; - // Read in the room bounding areas int size = rrmStream->readUint16LE(); Common::SeekableReadStream *boundsStream = !_lzwMode ? rrmStream : -- cgit v1.2.3 From ac642fdfb3689612f6efb263cc89419c55f019fa Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 30 Apr 2015 23:16:03 -1000 Subject: SHERLOCK: Implement custom mirror logic for scene 12 --- engines/sherlock/scalpel/scalpel.cpp | 85 ++++++++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 488a4de772..69bafa8d67 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -626,21 +626,100 @@ void ScalpelEngine::startScene() { * Takes care of clearing the mirror in scene 12, in case anything drew over it */ void ScalpelEngine::eraseMirror12() { - // TODO + Common::Point pt((*_people)[AL]._position.x / 100, (*_people)[AL]._position.y / 100); + + // If player is in range of the mirror, then restore background from the secondary back buffer + if (Common::Rect(70, 100, 200, 200).contains(pt)) { + _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(137, 18), + Common::Rect(137, 18, 184, 74)); + } } /** * Takes care of drawing Holme's reflection onto the mirror in scene 12 */ void ScalpelEngine::doMirror12() { - // TODO + People &people = *_people; + Common::Point pt((*_people)[AL]._position.x / 100, (*_people)[AL]._position.y / 100); + int frameNum = (*people[AL]._sequences)[people[AL]._sequenceNumber][people[AL]._frameNumber] + + (*people[AL]._sequences)[people[AL]._sequenceNumber][0] - 2; + + switch ((*_people)[AL]._sequenceNumber) { + case WALK_DOWN: + frameNum -= 7; + break; + case WALK_UP: + frameNum += 7; + break; + case WALK_DOWNRIGHT: + frameNum += 7; + break; + case WALK_UPRIGHT: + frameNum -= 7; + break; + case WALK_DOWNLEFT: + frameNum += 7; + break; + case WALK_UPLEFT: + frameNum -= 7; + break; + case STOP_DOWN: + frameNum -= 10; + break; + case STOP_UP: + frameNum += 11; + break; + case STOP_DOWNRIGHT: + frameNum -= 15; + break; + case STOP_DOWNLEFT: + frameNum -= 15; + break; + case STOP_UPRIGHT: + case STOP_UPLEFT: + frameNum += 15; + if (frameNum == 55) + frameNum = 54; + break; + default: + break; + } + + if (Common::Rect(80, 100, 145, 138).contains(pt)) { + // Get the frame of Sherlock to draw + ImageFrame &imageFrame = (*people[AL]._images)[frameNum]; + + // Draw the mirror image of Holmes + bool flipped = people[AL]._sequenceNumber == WALK_LEFT || people[AL]._sequenceNumber == STOP_LEFT + || people[AL]._sequenceNumber == WALK_UPRIGHT || people[AL]._sequenceNumber == STOP_UPRIGHT + || people[AL]._sequenceNumber == WALK_DOWNLEFT || people[AL]._sequenceNumber == STOP_DOWNLEFT; + _screen->transBlitFrom(imageFrame, pt + Common::Point(38, imageFrame._frame.h - 25), flipped); + + // Redraw the mirror borders to prevent the drawn image of Holmes from appearing outside of the mirror + _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(114, 18), + Common::Rect(114, 18, 137, 114)); + _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(137, 70), + Common::Rect(137, 70, 142, 114)); + _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(142, 71), + Common::Rect(142, 71, 159, 114)); + _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(159, 72), + Common::Rect(159, 72, 170, 116)); + _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(170, 73), + Common::Rect(170, 73, 184, 114)); + _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(184, 18), + Common::Rect(184, 18, 212, 114)); + } } /** * This clears the mirror in scene 12 in case anything messed draw over it */ void ScalpelEngine::flushMirror12() { - // TODO + Common::Point pt((*_people)[AL]._position.x / 100, (*_people)[AL]._position.y / 100); + + // If player is in range of the mirror, then draw the entire mirror area to the screen + if (Common::Rect(70, 100, 200, 200).contains(pt)) + _screen->slamArea(137, 18, 47, 56); } } // End of namespace Scalpel -- cgit v1.2.3 From ffd65cfd36841f6e117d800043d1cf695951f8a9 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 09:57:19 -1000 Subject: SHERLOCK: Fix animation for retrieving pocket watch --- engines/sherlock/objects.cpp | 2 ++ engines/sherlock/scene.cpp | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 3dc50e61b1..3cec0d800a 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -719,6 +719,8 @@ bool Object::checkEndOfSequence() { // Free the images delete _images; + _images = nullptr; + _imageFrame = nullptr; } } else { _type = INVALID; diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index ec7831820a..a9763a7fc5 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -1050,6 +1050,12 @@ int Scene::startCAnim(int cAnimNum, int playRate) { // Set canim to REMOVE type and free memory cObj.checkObject(); + for (uint idx = 0; idx < _canimShapes.size(); ++idx) { + if (&_canimShapes[idx] == &cObj) { + _canimShapes.remove_at(idx); + break; + } + } if (gotoCode > 0 && !talk._talkToAbort) { _goToScene = gotoCode; @@ -1376,7 +1382,7 @@ void Scene::doBgAnim() { if (_goToScene == -1) screen.slamArea(o._position.x, o._position.y, o._delta.x, o._delta.y); - _canimShapes.remove_at(idx); + _canimShapes[idx]._type = INVALID; if (_ongoingCans > 0) --_ongoingCans; } else if (o._type == ACTIVE_BG_SHAPE) { -- cgit v1.2.3 From b8372695ebc3b266f9fbe074dbbdd8e3015ce547 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 10:08:14 -1000 Subject: SHERLOCK: Refactored out _ongoingCans field --- engines/sherlock/scene.cpp | 8 +------- engines/sherlock/scene.h | 1 - engines/sherlock/talk.cpp | 2 +- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index a9763a7fc5..55cdde2f56 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -91,7 +91,6 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { _changes = false; _keyboardInput = 0; _walkedInScene = false; - _ongoingCans = 0; _version = 0; _lzwMode = false; _invGraphicItems = 0; @@ -201,7 +200,6 @@ bool Scene::loadScene(const Common::String &filename) { bool flag; _walkedInScene = false; - _ongoingCans = 0; // Reset the list of walkable areas _zones.clear(); @@ -962,8 +960,6 @@ int Scene::startCAnim(int cAnimNum, int playRate) { cObj._imageFrame = &(*cObj._images)[0]; cObj._maxFrames = cObj._images->size(); - ++_ongoingCans; - int frames = 0; if (playRate < 0) { // Reverse direction @@ -1317,7 +1313,7 @@ void Scene::doBgAnim() { _animating = 0; screen.slamRect(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); } else { - if (people[AL]._type != INVALID && ((_goToScene == -1 || _ongoingCans == 0))) { + if (people[AL]._type != INVALID && ((_goToScene == -1 || _canimShapes.size() == 0))) { if (people[AL]._type == REMOVE) { screen.slamRect(Common::Rect( people[AL]._oldPosition.x, people[AL]._oldPosition.y, @@ -1383,8 +1379,6 @@ void Scene::doBgAnim() { screen.slamArea(o._position.x, o._position.y, o._delta.x, o._delta.y); _canimShapes[idx]._type = INVALID; - if (_ongoingCans > 0) - --_ongoingCans; } else if (o._type == ACTIVE_BG_SHAPE) { screen.flushImage(o._imageFrame, o._position, &o._oldPosition.x, &o._oldPosition.y, &o._oldSize.x, &o._oldSize.y); diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 159f281bdf..4fb7ac228a 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -111,7 +111,6 @@ public: int _oldKey, _help, _oldHelp; int _oldTemp, _temp; bool _walkedInScene; - int _ongoingCans; int _version; bool _lzwMode; int _invGraphicItems; diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index da72125f72..a848e11392 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -134,7 +134,7 @@ void Talk::talkTo(const Common::String &filename) { // If there any canimations currently running, or a portrait is being cleared, // save the filename for later executing when the canimation is done - if (scene._ongoingCans || people._clearingThePortrait) { + if (scene._canimShapes.size() > 0 || people._clearingThePortrait) { // Make sure we're not in the middle of a script if (!_scriptMoreFlag) { _scriptName = filename; -- cgit v1.2.3 From 3f5c159068fdee253883e300cae524282db5b167 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 10:24:53 -1000 Subject: SHERLOCK: Fix opening pocketwatch --- engines/sherlock/scene.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 55cdde2f56..cd913f8515 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -527,7 +527,7 @@ void Scene::checkSceneFlags(bool flag) { } } - // Check inventory + // Check inventory for items to remove based on flag changes for (int idx = 0; idx < _vm->_inventory->_holdings; ++idx) { InventoryItem &ii = (*_vm->_inventory)[idx]; if (ii._requiredFlag && !_vm->readFlags(ii._requiredFlag)) { @@ -536,10 +536,10 @@ void Scene::checkSceneFlags(bool flag) { _vm->_inventory->insert_at(_vm->_inventory->_holdings, tempItem); _vm->_inventory->remove_at(idx); _vm->_inventory->_holdings--; - break; } } + // Check inactive inventory items for ones to reactivate based on flag changes for (uint idx = _vm->_inventory->_holdings; idx < _vm->_inventory->size(); ++idx) { InventoryItem &ii = (*_vm->_inventory)[idx]; if (ii._requiredFlag && _vm->readFlags(ii._requiredFlag)) { @@ -548,7 +548,6 @@ void Scene::checkSceneFlags(bool flag) { _vm->_inventory->remove_at(idx); _vm->_inventory->insert_at(_vm->_inventory->_holdings, tempItem); _vm->_inventory->_holdings++; - break; } } } -- cgit v1.2.3 From edec4abfe5cace1b5a0761adc33bf8e526561f27 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 11:48:41 -1000 Subject: SHERLOCK: Fix mirror display in scene 12 --- engines/sherlock/scalpel/scalpel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 69bafa8d67..d36f761239 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -693,7 +693,7 @@ void ScalpelEngine::doMirror12() { bool flipped = people[AL]._sequenceNumber == WALK_LEFT || people[AL]._sequenceNumber == STOP_LEFT || people[AL]._sequenceNumber == WALK_UPRIGHT || people[AL]._sequenceNumber == STOP_UPRIGHT || people[AL]._sequenceNumber == WALK_DOWNLEFT || people[AL]._sequenceNumber == STOP_DOWNLEFT; - _screen->transBlitFrom(imageFrame, pt + Common::Point(38, imageFrame._frame.h - 25), flipped); + _screen->_backBuffer1.transBlitFrom(imageFrame, pt + Common::Point(38, -imageFrame._frame.h - 25), flipped); // Redraw the mirror borders to prevent the drawn image of Holmes from appearing outside of the mirror _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(114, 18), -- cgit v1.2.3 From da75ee1f8b233cbfacfd1f18a1be970edbc0b0f2 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 12:29:40 -1000 Subject: SHERLOCK: Fix display of animation cutscenes --- engines/sherlock/animation.cpp | 9 +++++---- engines/sherlock/resources.cpp | 20 ++++++++++++++------ engines/sherlock/resources.h | 4 ++-- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 810c0ecc34..e70bc84ff8 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -94,7 +94,7 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f // Load initial image Common::String vdaName = baseName + ".vda"; - ImageFile images(vdaName, true); + ImageFile images(vdaName, true, true); events.wait(minDelay); if (fade != 0 && fade != 255) @@ -119,15 +119,16 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f } else if (imageFrame != -1) { // Read position from either animation stream or the sprite frame itself if (imageFrame < 0) { - imageFrame += 32769; + imageFrame += 32768; pt.x = stream->readUint16LE(); pt.y = stream->readUint16LE(); } else { pt = images[imageFrame]._offset; } - // Draw the sprite - screen.transBlitFrom(images[imageFrame], pt); + // Draw the sprite. Note that we explicitly use the raw frame below, rather than the ImageFrame, + // since we don't want the offsets in the image file to be used, just the explicit position we specify + screen.transBlitFrom(images[imageFrame]._frame, pt); } else { // No sprite to show for this animation frame if (fade == 255) { diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index 0d66646286..788cacf82a 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -268,18 +268,18 @@ void ImageFile::setVm(SherlockEngine *vm) { _vm = vm; } -ImageFile::ImageFile(const Common::String &name, bool skipPal) { +ImageFile::ImageFile(const Common::String &name, bool skipPal, bool animImages) { Common::SeekableReadStream *stream = _vm->_res->load(name); Common::fill(&_palette[0], &_palette[PALETTE_SIZE], 0); - load(*stream, skipPal); + load(*stream, skipPal, animImages); delete stream; } ImageFile::ImageFile(Common::SeekableReadStream &stream, bool skipPal) { Common::fill(&_palette[0], &_palette[PALETTE_SIZE], 0); - load(stream, skipPal); + load(stream, skipPal, false); } ImageFile::~ImageFile() { @@ -290,7 +290,7 @@ ImageFile::~ImageFile() { /** * Load the data of the sprite */ -void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette) { +void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette, bool animImages) { loadPalette(stream); while (stream.pos() < stream.size()) { @@ -298,8 +298,16 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette) { frame._width = stream.readUint16LE() + 1; frame._height = stream.readUint16LE() + 1; frame._paletteBase = stream.readByte(); - frame._rleEncoded = stream.readByte() == 1; - frame._offset.x = stream.readByte(); + + if (animImages) { + // Animation cutscene image files use a 16-bit x offset + frame._offset.x = stream.readUint16LE(); + frame._rleEncoded = (frame._offset.x & 0xff) == 1; + } else { + // Standard image files have a separate byte for the RLE flag, and an 8-bit X offset + frame._rleEncoded = stream.readByte() == 1; + frame._offset.x = stream.readByte(); + } frame._offset.y = stream.readByte(); frame._rleEncoded = !skipPalette && frame._rleEncoded; diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h index 45fda565bc..b173884322 100644 --- a/engines/sherlock/resources.h +++ b/engines/sherlock/resources.h @@ -104,13 +104,13 @@ class ImageFile : public Common::Array { private: static SherlockEngine *_vm; - void load(Common::SeekableReadStream &stream, bool skipPalette); + void load(Common::SeekableReadStream &stream, bool skipPalette, bool animImages); void loadPalette(Common::SeekableReadStream &stream); void decompressFrame(ImageFrame &frame, const byte *src); public: byte _palette[256 * 3]; public: - ImageFile(const Common::String &name, bool skipPal = false); + ImageFile(const Common::String &name, bool skipPal = false, bool animImages = false); ImageFile(Common::SeekableReadStream &stream, bool skipPal = false); ~ImageFile(); static void setVm(SherlockEngine *vm); -- cgit v1.2.3 From 093d7877e6656132ed136fb37559a4daf82cd985 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 14:22:21 -1000 Subject: SHERLOCK: Fix conversation with Lord Brumwell --- engines/sherlock/talk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index a848e11392..7464e4d341 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -909,7 +909,7 @@ void Talk::setSequence(int speaker) { Scene &scene = *_vm->_scene; // If no speaker is specified, then nothing needs to be done - if (speaker != -1) + if (speaker == -1) return; if (speaker) { -- cgit v1.2.3 From a4662b4699286a948644a8018d343f96e28ee019 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 14:22:35 -1000 Subject: SHERLOCK: Fix getting Tarot cards --- engines/sherlock/scene.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index cd913f8515..497a8d551c 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -559,7 +559,7 @@ void Scene::checkSceneFlags(bool flag) { */ void Scene::checkInventory() { for (uint shapeIdx = 0; shapeIdx < _bgShapes.size(); ++shapeIdx) { - for (uint invIdx = 0; invIdx < _vm->_inventory->size(); ++invIdx) { + for (uint invIdx = 0; invIdx < _vm->_inventory->_holdings; ++invIdx) { if (scumm_stricmp(_bgShapes[shapeIdx]._name.c_str(), (*_vm->_inventory)[invIdx]._name.c_str()) == 0) { _bgShapes[shapeIdx]._type = INVALID; -- cgit v1.2.3 From 5b8fb0cf9097d3d288a3afe0615b6dffbaef3ea0 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 14:54:28 -1000 Subject: SHERLOCK: Fix crash unlocking desk drawer in Palmist --- engines/sherlock/objects.cpp | 7 +++++++ engines/sherlock/objects.h | 1 + 2 files changed, 8 insertions(+) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 3cec0d800a..ff8f6393db 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -377,6 +377,13 @@ void ActionType::synchronize(Common::SeekableReadStream &s) { /*----------------------------------------------------------------*/ +UseType::UseType() { + _cAnimNum = _cAnimSpeed = 0; + _useFlag = 0; + _dFlag[0] = 0; + _lFlag[0] = _lFlag[1] = 0; +} + void UseType::synchronize(Common::SeekableReadStream &s) { char buffer[12]; diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index e2b53ec541..10b491e5d7 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -160,6 +160,7 @@ struct UseType { int _lFlag[2]; Common::String _target; + UseType(); void synchronize(Common::SeekableReadStream &s); }; -- cgit v1.2.3 From 8671d29627821292dee5e950fdd17454ca289ee7 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 15:58:47 -1000 Subject: SHERLOCK: Re-enabled intro credits --- engines/sherlock/sherlock.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index a8d3d9a535..49230f22de 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -107,8 +107,7 @@ Common::Error SherlockEngine::run() { _saves->loadGame(_loadGameSlot); _loadGameSlot = -1; } else { - // Temporarily disabled for now - // showOpening(); + showOpening(); } while (!shouldQuit()) { -- cgit v1.2.3 From 9fd73d0b9a689166aed05fc36f39307ac016bcb9 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 15:59:36 -1000 Subject: SHERLOCK: Implemented showLBV and fixes for credits display --- engines/sherlock/scalpel/scalpel.cpp | 63 +++++++++++++++++++++++++----------- engines/sherlock/scalpel/scalpel.h | 2 ++ engines/sherlock/screen.cpp | 1 + 3 files changed, 48 insertions(+), 18 deletions(-) diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index d36f761239..c0910c52a1 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -330,9 +330,7 @@ bool ScalpelEngine::showAlleyCutscene() { finished = _animation->playPrologue("27PRO2", 1, 0, false, 2); if (finished) { - ImageFile screamImages("SCREAM.LBV", false); - _screen->_backBuffer1.transBlitFrom(screamImages[0], Common::Point(0, 0)); - _screen->_backBuffer2.blitFrom(_screen->_backBuffer1); + showLBV("scream.lbv"); finished = _events->delay(6000); } @@ -373,29 +371,40 @@ bool ScalpelEngine::showStreetCutscene() { return finished; } +/** + * Show the game credits + */ bool ScalpelEngine::scrollCredits() { + // Load the images for displaying credit text _titleOverride = "TITLE.LIB"; ImageFile creditsImages("credits.vgs", true); + _screen->setPalette(creditsImages._palette); + _titleOverride = ""; - _screen->_backBuffer1.copyFrom(*_screen->_backBuffer); + // Save a copy of the screen background for use in drawing each credit frame + _screen->_backBuffer1.blitFrom(*_screen); - for(int i = 0; i < 600 && !_events->kbHit(); i++) { - _screen->_backBuffer1.copyFrom(*_screen->_backBuffer); - if (i < 200) - _screen->transBlitFrom(creditsImages[0], Common::Point(10, -i), false, 0); - if (i > 0 && i < 400) - _screen->transBlitFrom(creditsImages[1], Common::Point(10, 200 - i), false, 0); - if (i > 200) - _screen->transBlitFrom(creditsImages[2], Common::Point(10, 400 - i), false, 0); + // Loop for showing the credits + for(int idx = 0; idx < 600 && !_events->kbHit() && !shouldQuit(); ++idx) { + // Copy the entire screen background before writing text + _screen->blitFrom(_screen->_backBuffer1); - warning("TODO: Use VideoBlockMove"); -// videoblockmove(SCREEN, BACKBUFFER, 0, 0, 320, 10); -// videoblockmove(SCREEN, BACKBUFFER, 0, 190, 320, 10); + // Write the text appropriate for the next frame + if (idx < 200) + _screen->transBlitFrom(creditsImages[0], Common::Point(10, -idx), false, 0); + if (idx > 0 && idx < 400) + _screen->transBlitFrom(creditsImages[1], Common::Point(10, 200 - idx), false, 0); + if (idx > 200) + _screen->transBlitFrom(creditsImages[2], Common::Point(10, 400 - idx), false, 0); + + // Don't show credit text on the top and bottom ten rows of the screen + _screen->blitFrom(_screen->_backBuffer1, Common::Point(0, 0), Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, 10)); + _screen->blitFrom(_screen->_backBuffer1, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - 10), + Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - 10, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); _events->delay(100); } - _titleOverride = ""; return true; } @@ -408,7 +417,8 @@ bool ScalpelEngine::showOfficeCutscene() { if (finished) finished = _animation->playPrologue("COFF2", 1, 0, false, 3); if (finished) { - warning("TODO: ShowLBV(""NOTE.LBV"");"); + showLBV("note.lbv"); + if (_sound->_voices) { finished = _sound->playSound("NOTE1", WAIT_KBD_OR_FINISH); if (finished) @@ -441,6 +451,11 @@ bool ScalpelEngine::showOfficeCutscene() { return finished; } +/** + * Load the default inventory for the game, which includes both the initial active inventory, + * as well as special pending inventory items which can appear automatically in the player's + * inventory once given required flags are set + */ void ScalpelEngine::loadInventory() { Inventory &inv = *_inventory; @@ -449,7 +464,7 @@ void ScalpelEngine::loadInventory() { inv.push_back(InventoryItem(0, "Message", "A message requesting help", "_ITEM03A")); inv.push_back(InventoryItem(0, "Holmes Card", "A number of business cards", "_ITEM07A")); - // Potential items + // Hidden items inv.push_back(InventoryItem(95, "Tickets", "Opera Tickets", "_ITEM10A")); inv.push_back(InventoryItem(138, "Cuff Link", "Cuff Link", "_ITEM04A")); inv.push_back(InventoryItem(138, "Wire Hook", "Wire Hook", "_ITEM06A")); @@ -462,6 +477,18 @@ void ScalpelEngine::loadInventory() { inv.push_back(InventoryItem(586, "Pawn ticket", "A pawn ticket", "_ITEM16A")); }; +/** + * Transition to show an image + */ +void ScalpelEngine::showLBV(const Common::String &filename) { + Common::SeekableReadStream *stream = _res->load(filename, "title.lib"); + ImageFile images(*stream); + delete stream; + + _screen->setPalette(images._palette); + _screen->_backBuffer1.blitFrom(images[0]._frame); + _screen->verticalTransition(); +} /** * Starting a scene within the game diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h index 194bf5413e..2ba47a49e1 100644 --- a/engines/sherlock/scalpel/scalpel.h +++ b/engines/sherlock/scalpel/scalpel.h @@ -42,6 +42,8 @@ private: bool scrollCredits(); void loadInventory(); + + void showLBV(const Common::String &filename); protected: virtual void initialize(); diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 66590c3ada..01d3b9155a 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -35,6 +35,7 @@ Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCR _transitionSeed = 1; _fadeStyle = false; _font = nullptr; + _backBuffer = nullptr; _fontHeight = 0; Common::fill(&_cMap[0], &_cMap[PALETTE_SIZE], 0); Common::fill(&_sMap[0], &_sMap[PALETTE_SIZE], 0); -- cgit v1.2.3 From cce0b5583160f1ea2aee2b294527e036165a84f1 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 16:06:45 -1000 Subject: SHERLOCK: Extra comments for methods in ScalpelEngine --- engines/sherlock/scalpel/scalpel.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index c0910c52a1..5274cbbec4 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -246,6 +246,9 @@ void ScalpelEngine::showOpening() { _sound->stopMusic(); } +/** + * Show the starting city cutscene which shows the game title + */ bool ScalpelEngine::showCityCutscene() { byte palette[PALETTE_SIZE]; @@ -318,6 +321,9 @@ bool ScalpelEngine::showCityCutscene() { return finished; } +/** + * Show the back alley where the initial murder takes place + */ bool ScalpelEngine::showAlleyCutscene() { byte palette[PALETTE_SIZE]; _sound->playMusic("prolog2.mus"); @@ -355,6 +361,9 @@ bool ScalpelEngine::showAlleyCutscene() { return finished; } +/** + * Show the Baker Street outside cutscene + */ bool ScalpelEngine::showStreetCutscene() { _titleOverride = "TITLE.LIB"; _soundOverride = "TITLE.SND"; @@ -408,6 +417,9 @@ bool ScalpelEngine::scrollCredits() { return true; } +/** + * Show Holmes and Watson at the breakfast table, lestrade's note, and then the scrolling credits + */ bool ScalpelEngine::showOfficeCutscene() { _sound->playMusic("PROLOG4.MUS"); _titleOverride = "TITLE2.LIB"; -- cgit v1.2.3 From 1e2ed9e3bc98ad7b0295df8484710a8223bfd01d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 16:32:09 -1000 Subject: SHERLOCK: Further fixes for credits display --- engines/sherlock/scalpel/scalpel.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 5274cbbec4..a90408fe11 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -385,10 +385,10 @@ bool ScalpelEngine::showStreetCutscene() { */ bool ScalpelEngine::scrollCredits() { // Load the images for displaying credit text - _titleOverride = "TITLE.LIB"; - ImageFile creditsImages("credits.vgs", true); + Common::SeekableReadStream *stream = _res->load("credits.vgs", "title.lib"); + ImageFile creditsImages(*stream); _screen->setPalette(creditsImages._palette); - _titleOverride = ""; + delete stream; // Save a copy of the screen background for use in drawing each credit frame _screen->_backBuffer1.blitFrom(*_screen); @@ -399,12 +399,10 @@ bool ScalpelEngine::scrollCredits() { _screen->blitFrom(_screen->_backBuffer1); // Write the text appropriate for the next frame - if (idx < 200) - _screen->transBlitFrom(creditsImages[0], Common::Point(10, -idx), false, 0); - if (idx > 0 && idx < 400) - _screen->transBlitFrom(creditsImages[1], Common::Point(10, 200 - idx), false, 0); + if (idx < 400) + _screen->transBlitFrom(creditsImages[0], Common::Point(10, 200 - idx), false, 0); if (idx > 200) - _screen->transBlitFrom(creditsImages[2], Common::Point(10, 400 - idx), false, 0); + _screen->transBlitFrom(creditsImages[1], Common::Point(10, 400 - idx), false, 0); // Don't show credit text on the top and bottom ten rows of the screen _screen->blitFrom(_screen->_backBuffer1, Common::Point(0, 0), Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, 10)); -- cgit v1.2.3 From 42a99354f9d0c4719e955008f57bf433fdbeabb3 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 16:53:22 -1000 Subject: SHERLOCK: Rename playPrologue to play --- engines/sherlock/animation.cpp | 2 +- engines/sherlock/animation.h | 2 +- engines/sherlock/scalpel/scalpel.cpp | 46 ++++++++++++++++++------------------ engines/sherlock/talk.cpp | 2 +- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index e70bc84ff8..1d84a30c0f 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -64,7 +64,7 @@ static const int NO_FRAMES = FRAMES_END; Animation::Animation(SherlockEngine *vm): _vm(vm) { } -bool Animation::playPrologue(const Common::String &filename, int minDelay, int fade, +bool Animation::play(const Common::String &filename, int minDelay, int fade, bool setPalette, int speed) { Events &events = *_vm->_events; Screen &screen = *_vm->_screen; diff --git a/engines/sherlock/animation.h b/engines/sherlock/animation.h index da4c5baad7..3d87cb0a91 100644 --- a/engines/sherlock/animation.h +++ b/engines/sherlock/animation.h @@ -39,7 +39,7 @@ public: public: Animation(SherlockEngine *vm); - bool playPrologue(const Common::String &filename, int minDelay, int fade, bool setPalette, int speed); + bool play(const Common::String &filename, int minDelay, int fade, bool setPalette, int speed); }; } // End of namespace Sherlock diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index a90408fe11..3fe094bcf4 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -255,7 +255,7 @@ bool ScalpelEngine::showCityCutscene() { _sound->playMusic("prolog1.mus"); _titleOverride = "title.lib"; _soundOverride = "title.snd"; - bool finished = _animation->playPrologue("26open1", 1, 255, true, 2); + bool finished = _animation->play("26open1", 1, 255, true, 2); if (finished) { ImageFile titleImages("title2.vgs", true); @@ -280,7 +280,7 @@ bool ScalpelEngine::showCityCutscene() { } if (finished) - finished = _animation->playPrologue("26open2", 1, 0, false, 2); + finished = _animation->play("26open2", 1, 0, false, 2); if (finished) { ImageFile titleImages("title.vgs", true); @@ -331,9 +331,9 @@ bool ScalpelEngine::showAlleyCutscene() { _titleOverride = "TITLE.LIB"; _soundOverride = "TITLE.SND"; - bool finished = _animation->playPrologue("27PRO1", 1, 3, true, 2); + bool finished = _animation->play("27PRO1", 1, 3, true, 2); if (finished) - finished = _animation->playPrologue("27PRO2", 1, 0, false, 2); + finished = _animation->play("27PRO2", 1, 0, false, 2); if (finished) { showLBV("scream.lbv"); @@ -341,7 +341,7 @@ bool ScalpelEngine::showAlleyCutscene() { } if (finished) - finished = _animation->playPrologue("27PRO3", 1, 0, true, 2); + finished = _animation->play("27PRO3", 1, 0, true, 2); if(finished) { _screen->getPalette(palette); @@ -370,10 +370,10 @@ bool ScalpelEngine::showStreetCutscene() { _sound->playMusic("PROLOG3.MUS"); - bool finished = _animation->playPrologue("14KICK", 1, 3, true, 2); + bool finished = _animation->play("14KICK", 1, 3, true, 2); if (finished) - finished = _animation->playPrologue("14NOTE", 1, 0, false, 2); + finished = _animation->play("14NOTE", 1, 0, false, 2); _titleOverride = ""; _soundOverride = ""; @@ -423,9 +423,9 @@ bool ScalpelEngine::showOfficeCutscene() { _titleOverride = "TITLE2.LIB"; _soundOverride = "TITLE.SND"; - bool finished = _animation->playPrologue("COFF1", 1, 3, true, 3); + bool finished = _animation->play("COFF1", 1, 3, true, 3); if (finished) - finished = _animation->playPrologue("COFF2", 1, 0, false, 3); + finished = _animation->play("COFF2", 1, 0, false, 3); if (finished) { showLBV("note.lbv"); @@ -445,10 +445,10 @@ bool ScalpelEngine::showOfficeCutscene() { } if (finished) - finished = _animation->playPrologue("COFF3", 1, 0, true, 3); + finished = _animation->play("COFF3", 1, 0, true, 3); if (finished) - finished = _animation->playPrologue("COFF4", 1, 0, false, 3); + finished = _animation->play("COFF4", 1, 0, false, 3); if (finished) finished = scrollCredits(); @@ -541,8 +541,8 @@ void ScalpelEngine::startScene() { // Blackwood's capture _res->addToCache("final2.vda", "epilogue.lib"); _res->addToCache("final2.vdx", "epilogue.lib"); - _animation->playPrologue("final1", 1, 3, true, 4); - _animation->playPrologue("final2", 1, 0, false, 4); + _animation->play("final1", 1, 3, true, 4); + _animation->play("final2", 1, 0, false, 4); break; case 52: @@ -558,8 +558,8 @@ void ScalpelEngine::startScene() { _res->addToCache("finale4.vda", "EPILOG2.lib"); _res->addToCache("finale4.vdx", "EPILOG2.lib"); - _animation->playPrologue("finalr1", 1, 3, true, 4); - _animation->playPrologue("finalr2", 1, 0, false, 4); + _animation->play("finalr1", 1, 3, true, 4); + _animation->play("finalr2", 1, 0, false, 4); if (!_res->isInCache("finale2.vda")) { // Finale file isn't cached @@ -571,12 +571,12 @@ void ScalpelEngine::startScene() { _res->addToCache("finale4.vdx", "EPILOG2.lib"); } - _animation->playPrologue("finale1", 1, 0, false, 4); - _animation->playPrologue("finale2", 1, 0, false, 4); - _animation->playPrologue("finale3", 1, 0, false, 4); + _animation->play("finale1", 1, 0, false, 4); + _animation->play("finale2", 1, 0, false, 4); + _animation->play("finale3", 1, 0, false, 4); _useEpilogue2 = true; - _animation->playPrologue("finale4", 1, 0, false, 4); + _animation->play("finale4", 1, 0, false, 4); _useEpilogue2 = false; break; @@ -587,9 +587,9 @@ void ScalpelEngine::startScene() { _res->addToCache("SUBWAY3.vda", "epilogue.lib"); _res->addToCache("SUBWAY3.vdx", "epilogue.lib"); - _animation->playPrologue("SUBWAY1", 1, 3, true, 4); - _animation->playPrologue("SUBWAY2", 1, 0, false, 4); - _animation->playPrologue("SUBWAY3", 1, 0, false, 4); + _animation->play("SUBWAY1", 1, 3, true, 4); + _animation->play("SUBWAY2", 1, 0, false, 4); + _animation->play("SUBWAY3", 1, 0, false, 4); // Set fading to direct fade temporary so the transition goes quickly. _scene->_tempFadeStyle = _screen->_fadeStyle ? 257 : 256; @@ -598,7 +598,7 @@ void ScalpelEngine::startScene() { case 70: // Brumwell suicide - _animation->playPrologue("suicid", 1, 3, true, 4); + _animation->play("suicid", 1, 3, true, 4); break; default: break; diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 7464e4d341..603f47a446 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1353,7 +1353,7 @@ void Talk::doScript(const Common::String &script) { for (int idx = 0; idx < 8 && str[idx] != '~'; ++idx) tempString += str[idx]; - anim.playPrologue(tempString, 1, 3, true, 4); + anim.play(tempString, 1, 3, true, 4); break; case ADD_ITEM_TO_INVENTORY: -- cgit v1.2.3 From b4c3d9840c99ce5d4e23eb0f646bd995f7d2c002 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 17:17:24 -1000 Subject: SHERLOCK: Extra method comments --- engines/sherlock/animation.cpp | 3 +++ engines/sherlock/debugger.cpp | 6 ++++++ engines/sherlock/detection.cpp | 30 ++++++++++++++++++++++++++++++ engines/sherlock/events.cpp | 5 +++-- engines/sherlock/graphics.cpp | 9 +++++++-- engines/sherlock/inventory.cpp | 3 +++ engines/sherlock/journal.cpp | 3 +++ engines/sherlock/objects.cpp | 19 ++++++++++++++----- engines/sherlock/people.cpp | 14 ++++++++++---- engines/sherlock/scene.cpp | 5 ++++- engines/sherlock/screen.cpp | 15 +++++++++++++++ engines/sherlock/sherlock.cpp | 14 +++++++++++++- engines/sherlock/talk.cpp | 6 ++++++ engines/sherlock/user_interface.cpp | 17 +++++++++++++++-- 14 files changed, 132 insertions(+), 17 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 1d84a30c0f..aea4793a76 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -64,6 +64,9 @@ static const int NO_FRAMES = FRAMES_END; Animation::Animation(SherlockEngine *vm): _vm(vm) { } +/** + * Play a full-screen animation + */ bool Animation::play(const Common::String &filename, int minDelay, int fade, bool setPalette, int speed) { Events &events = *_vm->_events; diff --git a/engines/sherlock/debugger.cpp b/engines/sherlock/debugger.cpp index b8ac8bef6a..b3dac71d5e 100644 --- a/engines/sherlock/debugger.cpp +++ b/engines/sherlock/debugger.cpp @@ -30,6 +30,9 @@ Debugger::Debugger(SherlockEngine *vm) : GUI::Debugger(), _vm(vm) { registerCmd("scene", WRAP_METHOD(Debugger, cmd_scene)); } +/** + * Converts a decimal or hexadecimal string into a number + */ static int strToInt(const char *s) { if (!*s) // No string at all @@ -46,6 +49,9 @@ static int strToInt(const char *s) { return (int)tmp; } +/** + * Switch to another scene + */ bool Debugger::cmd_scene(int argc, const char **argv) { if (argc != 2) { debugPrintf("Format: scene \n"); diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp index c4d1c65fd5..14fc04cc73 100644 --- a/engines/sherlock/detection.cpp +++ b/engines/sherlock/detection.cpp @@ -36,14 +36,23 @@ struct SherlockGameDescription { uint32 features; }; +/** + * Returns the Id of the game + */ uint32 SherlockEngine::getGameID() const { return _gameDescription->gameID; } +/** + * Returns the features the currently playing game has + */ uint32 SherlockEngine::getGameFeatures() const { return _gameDescription->features; } +/** + * Return's the platform the game's datafiles are for + */ Common::Platform SherlockEngine::getPlatform() const { return _gameDescription->desc.platform; } @@ -79,6 +88,9 @@ public: SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const; }; +/** + * Creates an instance of the game engine + */ bool SherlockMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { const Sherlock::SherlockGameDescription *gd = (const Sherlock::SherlockGameDescription *)desc; if (gd) { @@ -97,6 +109,9 @@ bool SherlockMetaEngine::createInstance(OSystem *syst, Engine **engine, const AD return gd != 0; } +/** + * Returns a list of features the game's MetaEngine support + */ bool SherlockMetaEngine::hasFeature(MetaEngineFeature f) const { return (f == kSupportsListSaves) || @@ -106,6 +121,9 @@ bool SherlockMetaEngine::hasFeature(MetaEngineFeature f) const { (f == kSavesSupportThumbnail); } +/** + * Returns a list of features the game itself supports + */ bool Sherlock::SherlockEngine::hasFeature(EngineFeature f) const { return (f == kSupportsRTL) || @@ -113,19 +131,31 @@ bool Sherlock::SherlockEngine::hasFeature(EngineFeature f) const { (f == kSupportsSavingDuringRuntime); } +/** + * Return a list of savegames + */ SaveStateList SherlockMetaEngine::listSaves(const char *target) const { return Sherlock::SaveManager(nullptr, "").getSavegameList(target); } +/** + * Returns the maximum number of allowed save slots + */ int SherlockMetaEngine::getMaximumSaveSlot() const { return MAX_SAVEGAME_SLOTS; } +/** + * Deletes a savegame in the specified slot + */ void SherlockMetaEngine::removeSaveState(const char *target, int slot) const { Common::String filename = Sherlock::SaveManager(nullptr, target).generateSaveName(slot); g_system->getSavefileManager()->removeSavefile(filename); } +/** + * Given a specified savegame slot, returns extended information for the save + */ SaveStateDescriptor SherlockMetaEngine::querySaveMetaInfos(const char *target, int slot) const { Common::String filename = Sherlock::SaveManager(nullptr, target).generateSaveName(slot); Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(filename); diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index f7cbdd301e..a4fc93edd9 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -208,7 +208,6 @@ Common::KeyState Events::getKey() { return keyState; } - /** * Clear any current keypress or mouse click */ @@ -227,7 +226,6 @@ void Events::clearKeyboard() { _pendingKeys.clear(); } - /** * Delay for a given number of game frames, where each frame is 1/60th of a second */ @@ -236,6 +234,9 @@ void Events::wait(int numFrames) { delay(totalMilli); } +/** + * Does a delay of the specified number of milliseconds + */ bool Events::delay(uint32 time, bool interruptable) { // Different handling for really short versus extended times if (time < 10) { diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index 6fd046e458..2095e7d35d 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -47,6 +47,10 @@ Surface::~Surface() { free(); } +/** + * Sets up an internal surface with the specified dimensions that will be automatically freed + * when the surface object is destroyed + */ void Surface::create(uint16 width, uint16 height) { if (_freePixels) free(); @@ -55,7 +59,6 @@ void Surface::create(uint16 width, uint16 height) { _freePixels = true; } - /** * Copy a surface into this one */ @@ -159,6 +162,9 @@ void Surface::fillRect(int x1, int y1, int x2, int y2, byte color) { fillRect(Common::Rect(x1, y1, x2, y2), color); } +/** + * Fill a given area of the surface with a given color + */ void Surface::fillRect(const Common::Rect &r, byte color) { Graphics::Surface::fillRect(r, color); addDirtyRect(r); @@ -196,5 +202,4 @@ bool Surface::clip(Common::Rect &srcBounds, Common::Rect &destBounds) { return true; } - } // End of namespace Sherlock diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index 798531ea14..935a306619 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -358,6 +358,9 @@ void Inventory::highlight(int index, byte color) { screen.slamArea(8 + slot * 52, 165, 44, 30); } +/** + * Support method for updating the screen + */ void Inventory::doInvJF() { Screen &screen = *_vm->_screen; Talk &talk = *_vm->_talk; diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 67cff15218..25b0bb5451 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -91,6 +91,9 @@ void Journal::record(int converseNum, int statementNum, bool replyOnly) { } } +/** + * Load the list of location names that the journal will make reference to + */ void Journal::loadJournalLocations() { Resources &res = *_vm->_res; char c; diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index ff8f6393db..fa5dfee26c 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -361,6 +361,9 @@ void Sprite::checkSprite() { /*----------------------------------------------------------------*/ +/** + * Synchronize the data for a savegame + */ void ActionType::synchronize(Common::SeekableReadStream &s) { char buffer[12]; @@ -384,6 +387,9 @@ UseType::UseType() { _lFlag[0] = _lFlag[1] = 0; } +/** + * Synchronize the data for a savegame + */ void UseType::synchronize(Common::SeekableReadStream &s) { char buffer[12]; @@ -816,11 +822,11 @@ void Object::setObjSequence(int seq, bool wait) { } /** -* Checks for codes -* @param name The name to check for codes -* @param messages Provides a lookup list of messages that can be printed -* @returns 0 if no codes are found, 1 if codes were found -*/ + * Checks for codes + * @param name The name to check for codes + * @param messages Provides a lookup list of messages that can be printed + * @returns 0 if no codes are found, 1 if codes were found + */ int Object::checkNameForCodes(const Common::String &name, const char *const messages[]) { Map &map = *_vm->_map; People &people = *_vm->_people; @@ -1090,6 +1096,9 @@ const Common::Rect Object::getOldBounds() const { /*----------------------------------------------------------------*/ +/** + * Synchronize the data for a savegame + */ void CAnim::synchronize(Common::SeekableReadStream &s) { char buffer[12]; s.read(buffer, 12); diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index ed6e0607bd..5c4014f1a2 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -217,6 +217,9 @@ People::~People() { delete[] _portrait._sequences; } +/** + * Reset the player data + */ void People::reset() { Sprite &p = _data[PLAYER]; @@ -239,6 +242,9 @@ void People::reset() { p._status = 0; } +/** + * Load the walking images for Sherlock + */ bool People::loadWalk() { if (_walkLoaded) { return false; @@ -267,10 +273,10 @@ bool People::freeWalk() { } /** -* Set the variables for moving a character from one poisition to another -* in a straight line - goAllTheWay must have been previously called to -* check for any obstacles in the path. -*/ + * Set the variables for moving a character from one poisition to another + * in a straight line - goAllTheWay must have been previously called to + * check for any obstacles in the path. + */ void People::setWalking() { Map &map = *_vm->_map; Scene &scene = *_vm->_scene; diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 497a8d551c..c714574e08 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -559,7 +559,7 @@ void Scene::checkSceneFlags(bool flag) { */ void Scene::checkInventory() { for (uint shapeIdx = 0; shapeIdx < _bgShapes.size(); ++shapeIdx) { - for (uint invIdx = 0; invIdx < _vm->_inventory->_holdings; ++invIdx) { + for (int invIdx = 0; invIdx < _vm->_inventory->_holdings; ++invIdx) { if (scumm_stricmp(_bgShapes[shapeIdx]._name.c_str(), (*_vm->_inventory)[invIdx]._name.c_str()) == 0) { _bgShapes[shapeIdx]._type = INVALID; @@ -802,6 +802,9 @@ void Scene::updateBackground() { screen.resetDisplayBounds(); } +/** + * Check whether the passed area intersects with one of the scene's exits + */ Exit *Scene::checkForExit(const Common::Rect &r) { for (uint idx = 0; idx < _exits.size(); ++idx) { if (_exits[idx]._bounds.intersects(r)) diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 01d3b9155a..97b23e7c8e 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -50,6 +50,9 @@ Screen::~Screen() { delete _font; } +/** + * Set the font to use for writing text on the screen + */ void Screen::setFont(int fontNumber) { _fontNumber = fontNumber; Common::String fname = Common::String::format("FONT%d.VGS", fontNumber + 1); @@ -64,6 +67,9 @@ void Screen::setFont(int fontNumber) { _fontHeight = MAX((uint16)_fontHeight, (*_font)[idx]._frame.h); } +/** + * Handles updating any dirty areas of the screen Surface object to the physical screen + */ void Screen::update() { // Merge the dirty rects mergeDirtyRects(); @@ -82,14 +88,23 @@ void Screen::update() { _dirtyRects.clear(); } +/** + * Return the currently active palette + */ void Screen::getPalette(byte palette[PALETTE_SIZE]) { g_system->getPaletteManager()->grabPalette(palette, 0, PALETTE_COUNT); } +/** + * Set the palette + */ void Screen::setPalette(const byte palette[PALETTE_SIZE]) { g_system->getPaletteManager()->setPalette(palette, 0, PALETTE_COUNT); } +/** + * Fades from the currently active palette to the passed palette + */ int Screen::equalizePalette(const byte palette[PALETTE_SIZE]) { int total = 0; byte tempPalette[PALETTE_SIZE]; diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 49230f22de..e3d137a3a3 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -69,6 +69,9 @@ SherlockEngine::~SherlockEngine() { delete _res; } +/** + * Does basic initialization of the game engine + */ void SherlockEngine::initialize() { initGraphics(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT, false); @@ -93,7 +96,11 @@ void SherlockEngine::initialize() { _ui = new UserInterface(this); } +/** + * Main method for running the game + */ Common::Error SherlockEngine::run() { + // Initialize the engine initialize(); // If requested, load a savegame instead of showing the intro @@ -133,6 +140,9 @@ Common::Error SherlockEngine::run() { return Common::kNoError; } +/** + * Main loop for displaying a scene and handling all that occurs within it + */ void SherlockEngine::sceneLoop() { while (!shouldQuit() && _scene->_goToScene == -1) { // See if a script needs to be completed from either a goto room code, @@ -171,7 +181,6 @@ void SherlockEngine::handleInput() { _ui->handleInput(); } - /** * Read the state of a global flag */ @@ -193,6 +202,9 @@ void SherlockEngine::setFlags(int flagNum) { _scene->checkSceneFlags(true); } +/** + * Saves game configuration information + */ void SherlockEngine::saveConfig() { // TODO } diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 603f47a446..d05c09ab38 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -100,6 +100,9 @@ Talk::Talk(SherlockEngine *vm): _vm(vm) { _scriptCurrentIndex = -1; } +/** + * Sets talk sequences + */ void Talk::setSequences(const byte *talkSequences, const byte *stillSequences, int maxPeople) { for (int idx = 0; idx < maxPeople; ++idx) { STILL_SEQUENCES.push_back(TalkSequences(stillSequences)); @@ -1726,6 +1729,9 @@ int Talk::waitForMore(int delay) { return key2; } +/** + * Pops an entry off of the script stack + */ void Talk::popStack() { if (!_scriptStack.empty()) { ScriptStackEntry scriptEntry = _scriptStack.pop(); diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index e7e7981966..f60e63a574 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -188,6 +188,9 @@ void Settings::drawInteface(bool flag) { } } +/** + * Draws the buttons for the settings dialog + */ int Settings::drawButtons(const Common::Point &pt, int _key) { Events &events = *_vm->_events; People &people = *_vm->_people; @@ -259,7 +262,6 @@ int Settings::drawButtons(const Common::Point &pt, int _key) { return found; } - /*----------------------------------------------------------------*/ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { @@ -298,6 +300,9 @@ UserInterface::~UserInterface() { delete _controlPanel; } +/** + * Resets the user interface + */ void UserInterface::reset() { _oldKey = -1; _help = _oldHelp = -1; @@ -1962,6 +1967,12 @@ void UserInterface::doTalkControl() { } } +/** + * Handles events when the Journal is active. + * @remarks Whilst this would in theory be better in the Journal class, since it displays in + * the user interface, it uses so many internal UI fields, that it sort of made some sense + * to put it in the UserInterface class. + */ void UserInterface::journalControl() { Events &events = *_vm->_events; Journal &journal = *_vm->_journal; @@ -2013,6 +2024,9 @@ void UserInterface::journalControl() { /** * Handles input when the settings window is being shown + * @remarks Whilst this would in theory be better in the Journal class, since it displays in + * the user interface, it uses so many internal UI fields, that it sort of made some sense + * to put it in the UserInterface class. */ void UserInterface::doControls() { Events &events = *_vm->_events; @@ -2702,5 +2716,4 @@ void UserInterface::checkAction(ActionType &action, const char *const messages[] events.setCursor(ARROW); } - } // End of namespace Sherlock -- cgit v1.2.3 From d9a42a80ffeb9eaee957bbc858f714e5cf362946 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 17:27:59 -1000 Subject: SHERLOCK: Fix some remaining TODOs --- engines/sherlock/scene.cpp | 4 +--- engines/sherlock/sound.cpp | 6 ++++++ engines/sherlock/sound.h | 1 + engines/sherlock/user_interface.cpp | 1 - 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index c714574e08..e69fb49766 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -1127,9 +1127,7 @@ void Scene::doBgAnim() { if (sound._diskSoundPlaying && !*sound._soundIsOn) { // Loaded sound just finished playing - // TODO: This is horrible.. refactor into the Sound class - delete[] sound._digiBuf; - sound._diskSoundPlaying = false; + sound.freeDigiSound(); } if (_restoreFlag) { diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index 1a6472a9e9..a452efd890 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -99,4 +99,10 @@ void Sound::waitTimerRoland(uint time) { // TODO } +void Sound::freeDigiSound() { + delete[] _digiBuf; + _digiBuf = nullptr; + _diskSoundPlaying = false; +} + } // End of namespace Sherlock diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index 28de692109..c85af2ac2a 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -67,6 +67,7 @@ public: void stopMusic(); void stopSndFuncPtr(int v1, int v2); void waitTimerRoland(uint time); + void freeDigiSound(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index f60e63a574..21a53c32ff 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -2019,7 +2019,6 @@ void UserInterface::journalControl() { screen._backBuffer1.blitFrom(screen._backBuffer2); scene.updateBackground(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); - // TODO } /** -- cgit v1.2.3 From 12d3976c380e00f22c6f7a930ff56c215a7bd9ab Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 18:21:13 -1000 Subject: SHERLOCK: Implement configuration settings save/load --- engines/sherlock/sherlock.cpp | 42 ++++++++++++++++++++++++++++++++++++++- engines/sherlock/sherlock.h | 3 +++ engines/sherlock/sound.cpp | 22 ++++++++++++++++---- engines/sherlock/sound.h | 7 ++++--- engines/sherlock/user_interface.h | 2 +- 5 files changed, 67 insertions(+), 9 deletions(-) diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index e3d137a3a3..3ab2caabc4 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -94,6 +94,9 @@ void SherlockEngine::initialize() { _sound = new Sound(this); _talk = new Talk(this); _ui = new UserInterface(this); + + // Load game settings + loadConfig(); } /** @@ -202,11 +205,48 @@ void SherlockEngine::setFlags(int flagNum) { _scene->checkSceneFlags(true); } +/** + * Load game configuration esttings + */ +void SherlockEngine::loadConfig() { + // Load sound settings + syncSoundSettings(); + + // Load other settings + if (ConfMan.hasKey("font")) + _screen->setFont(ConfMan.getInt("font")); + if (ConfMan.hasKey("help_style")) + _ui->_helpStyle = ConfMan.getInt("help_style"); + if (ConfMan.hasKey("window_style")) + _ui->_windowStyle = ConfMan.getInt("window_style"); + if (ConfMan.hasKey("portraits_on")) + _people->_portraitsOn = ConfMan.getBool("portraits_on"); +} + /** * Saves game configuration information */ void SherlockEngine::saveConfig() { - // TODO + ConfMan.setBool("mute", _sound->_digitized); + ConfMan.setBool("music_mute", _sound->_music); + ConfMan.setBool("speech_mute", _sound->_voices); + + ConfMan.setInt("font", _screen->fontNumber()); + ConfMan.setInt("help_style", _ui->_helpStyle); + ConfMan.setInt("window_style", _ui->_windowStyle); + ConfMan.setBool("portraits_on", _people->_portraitsOn); + + ConfMan.flushToDisk(); +} + +/** + * Called by the engine when sound settings are updated + */ +void SherlockEngine::syncSoundSettings() { + Engine::syncSoundSettings(); + + // Load sound-related settings + _sound->syncSoundSettings(); } /** diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 3f0779421c..02e2e99229 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -74,6 +74,8 @@ private: void sceneLoop(); void handleInput(); + + void loadConfig(); protected: virtual void initialize(); @@ -117,6 +119,7 @@ public: virtual bool canSaveGameStateCurrently(); virtual Common::Error loadGameState(int slot); virtual Common::Error saveGameState(int slot, const Common::String &desc); + virtual void syncSoundSettings(); int getGameType() const; uint32 getGameID() const; diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index a452efd890..e66f82e5c4 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -21,20 +21,34 @@ */ #include "sherlock/sound.h" +#include "common/config-manager.h" namespace Sherlock { Sound::Sound(SherlockEngine *vm): _vm(vm) { + _digitized = false; + _music = false; + _voices = 0; _soundOn = false; _musicOn = false; _speechOn = false; - _voices = 0; _playingEpilogue = false; - _music = false; - _digitized = false; _diskSoundPlaying = false; _soundIsOn = nullptr; - _digiBuf = nullptr; +} + +/** + * Saves sound-related settings + */ +void Sound::syncSoundSettings() { + _digitized = !ConfMan.getBool("mute"); + _music = !ConfMan.getBool("mute") && !ConfMan.getBool("music_mute"); + _voices = !ConfMan.getBool("mute") && !ConfMan.getBool("speech_mute") ? 1 : 0; + + // TODO: For now, keep sound completely mute until sound is implemented + _digitized = false; + _music = false; + _voices = 0; } void Sound::loadSound(const Common::String &name, int priority) { diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index c85af2ac2a..3bd3a99f07 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -38,19 +38,20 @@ class Sound { private: SherlockEngine *_vm; public: + bool _digitized; + bool _music; + int _voices; bool _soundOn; bool _musicOn; bool _speechOn; - int _voices; bool _playingEpilogue; - bool _music; - bool _digitized; bool _diskSoundPlaying; byte *_soundIsOn; byte *_digiBuf; public: Sound(SherlockEngine *vm); + void syncSoundSettings(); void loadSound(const Common::String &name, int priority); bool playSound(const Common::String &name, WaitType waitType = WAIT_RETURN_IMMEDIATELY); void cacheSound(const Common::String &name, int index); diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index 99612b218b..ac2c16d7c2 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -85,7 +85,6 @@ private: int _bgFound; int _oldBgFound; int _keycode; - int _helpStyle; int _lookHelp; int _help, _oldHelp; int _key, _oldKey; @@ -137,6 +136,7 @@ public: int _invLookFlag; int _temp1; int _windowStyle; + int _helpStyle; public: UserInterface(SherlockEngine *vm); ~UserInterface(); -- cgit v1.2.3 From 7d50c49f5942d2a2e6cfaf32ddc182bcff5c4327 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 18:22:25 -1000 Subject: SHERLOCK: Fix intro sequence crash --- engines/sherlock/screen.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 97b23e7c8e..d170772c98 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -35,7 +35,6 @@ Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCR _transitionSeed = 1; _fadeStyle = false; _font = nullptr; - _backBuffer = nullptr; _fontHeight = 0; Common::fill(&_cMap[0], &_cMap[PALETTE_SIZE], 0); Common::fill(&_sMap[0], &_sMap[PALETTE_SIZE], 0); -- cgit v1.2.3 From a2ef3e240225940308c54243589014c922c38274 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 18:29:42 -1000 Subject: SHERLOCK: Moved Settings dialog into it's own class --- engines/sherlock/module.mk | 1 + engines/sherlock/settings.cpp | 211 ++++++++++++++++++++++++++++++++++++ engines/sherlock/settings.h | 45 ++++++++ engines/sherlock/user_interface.cpp | 186 +------------------------------ engines/sherlock/user_interface.h | 11 -- 5 files changed, 258 insertions(+), 196 deletions(-) create mode 100644 engines/sherlock/settings.cpp create mode 100644 engines/sherlock/settings.h diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk index 44ba63f1e2..9334ebfd9c 100644 --- a/engines/sherlock/module.mk +++ b/engines/sherlock/module.mk @@ -19,6 +19,7 @@ MODULE_OBJS = \ saveload.o \ scene.o \ screen.o \ + settings.o \ sherlock.o \ sound.o \ talk.o \ diff --git a/engines/sherlock/settings.cpp b/engines/sherlock/settings.cpp new file mode 100644 index 0000000000..fb7730fc1d --- /dev/null +++ b/engines/sherlock/settings.cpp @@ -0,0 +1,211 @@ +/* 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 "sherlock/sherlock.h" +#include "sherlock/settings.h" + +namespace Sherlock { + +const int SETUP_POINTS[12][4] = { + { 4, 154, 101, 53 }, // Exit + { 4, 165, 101, 53 }, // Music Toggle + { 219, 165, 316, 268 }, // Voice Toggle + { 103, 165, 217, 160 }, // Sound Effects Toggle + { 219, 154, 316, 268 }, // Help Button Left/Right + { 103, 154, 217, 160 }, // New Font Style + { 4, 187, 101, 53 }, // Joystick Toggle + { 103, 187, 217, 160 }, // Calibrate Joystick + { 219, 176, 316, 268 }, // Fade Style + { 103, 176, 217, 160 }, // Window Open Style + { 4, 176, 101, 53 }, // Portraits Toggle + { 219, 187, 316, 268 } // _key Pad Accel. Toggle +}; + +const char *const SETUP_STRS0[2] = { "off", "on" }; +const char *const SETUP_STRS1[2] = { "Directly", "by Pixel" }; +const char *const SETUP_STRS2[2] = { "Left", "Right" }; +const char *const SETUP_STRS3[2] = { "Appear", "Slide" }; +const char *const SETUP_STRS4[2] = { "Slow", "Fast" }; +const char *const SETUP_STRS5[2] = { "Left", "Right" }; +const char *const SETUP_NAMES[12] = { + "Exit", "M", "V", "S", "B", "New Font Style", "J", "Calibrate Joystick", "F", "W", "P", "K" +}; + +/*----------------------------------------------------------------*/ + +/** + * Draws the interface for the settings window + */ +void Settings::drawInteface(bool flag) { + People &people = *_vm->_people; + Screen &screen = *_vm->_screen; + Sound &sound = *_vm->_sound; + UserInterface &ui = *_vm->_ui; + Common::String tempStr; + + if (!flag) { + screen._backBuffer1.fillRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y1 + 1), BORDER_COLOR); + screen._backBuffer1.fillRect(Common::Rect(0, CONTROLS_Y1 + 1, 2, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); + screen._backBuffer1.fillRect(Common::Rect(SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y1 + 1, SHERLOCK_SCREEN_WIDTH, + SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); + screen._backBuffer1.hLine(0, SHERLOCK_SCREEN_HEIGHT - 1, SHERLOCK_SCREEN_WIDTH - 1, BORDER_COLOR); + screen._backBuffer1.fillRect(Common::Rect(2, CONTROLS_Y1 + 1, SHERLOCK_SCREEN_WIDTH - 2, + SHERLOCK_SCREEN_HEIGHT - 2), INV_BACKGROUND); + } + + screen.makeButton(Common::Rect(SETUP_POINTS[0][0], SETUP_POINTS[0][1], SETUP_POINTS[0][2], SETUP_POINTS[0][1] + 10), + SETUP_POINTS[0][3] - screen.stringWidth("Exit") / 2, "Exit"); + + tempStr = Common::String::format("Music %s", SETUP_STRS0[sound._music]); + screen.makeButton(Common::Rect(SETUP_POINTS[1][0], SETUP_POINTS[1][1], SETUP_POINTS[1][2], SETUP_POINTS[1][1] + 10), + SETUP_POINTS[1][3] - screen.stringWidth(tempStr) / 2, tempStr); + + tempStr = Common::String::format("Voices %s", SETUP_STRS0[sound._voices]); + screen.makeButton(Common::Rect(SETUP_POINTS[2][0], SETUP_POINTS[2][1], SETUP_POINTS[2][2], SETUP_POINTS[2][1] + 10), + SETUP_POINTS[2][3] - screen.stringWidth(tempStr) / 2, tempStr); + + tempStr = Common::String::format("Sound Effects %s", SETUP_STRS0[sound._digitized]); + screen.makeButton(Common::Rect(SETUP_POINTS[3][0], SETUP_POINTS[3][1], SETUP_POINTS[3][2], SETUP_POINTS[3][1] + 10), + SETUP_POINTS[3][3] - screen.stringWidth(tempStr) / 2, tempStr); + + tempStr = Common::String::format("Auto Help %s", SETUP_STRS5[ui._helpStyle]); + screen.makeButton(Common::Rect(SETUP_POINTS[4][0], SETUP_POINTS[4][1], SETUP_POINTS[4][2], SETUP_POINTS[4][1] + 10), + SETUP_POINTS[4][3] - screen.stringWidth(tempStr) / 2, tempStr); + screen.makeButton(Common::Rect(SETUP_POINTS[5][0], SETUP_POINTS[5][1], SETUP_POINTS[5][2], SETUP_POINTS[5][1] + 10), + SETUP_POINTS[5][3] - screen.stringWidth("New Font Style") / 2, "New Font Style"); + + // WORKAROUND: We don't support the joystick in ScummVM, so draw the next two buttons as disabled + tempStr = "Joystick Off"; + screen.makeButton(Common::Rect(SETUP_POINTS[6][0], SETUP_POINTS[6][1], SETUP_POINTS[6][2], SETUP_POINTS[6][1] + 10), + SETUP_POINTS[6][3] - screen.stringWidth(tempStr) / 2, tempStr); + screen.buttonPrint(Common::Point(SETUP_POINTS[6][3], SETUP_POINTS[6][1]), COMMAND_NULL, false, tempStr); + + tempStr = "Calibrate Joystick"; + screen.makeButton(Common::Rect(SETUP_POINTS[7][0], SETUP_POINTS[7][1], SETUP_POINTS[7][2], SETUP_POINTS[7][1] + 10), + SETUP_POINTS[7][3] - screen.stringWidth(tempStr) / 2, tempStr); + screen.buttonPrint(Common::Point(SETUP_POINTS[7][3], SETUP_POINTS[7][1]), COMMAND_NULL, false, tempStr); + + tempStr = Common::String::format("Fade %s", screen._fadeStyle ? "by Pixel" : "Directly"); + screen.makeButton(Common::Rect(SETUP_POINTS[8][0], SETUP_POINTS[8][1], SETUP_POINTS[8][2], SETUP_POINTS[8][1] + 10), + SETUP_POINTS[8][3] - screen.stringWidth(tempStr) / 2, tempStr); + + tempStr = Common::String::format("Windows %s", ui._windowStyle ? "Slide" : "Appear"); + screen.makeButton(Common::Rect(SETUP_POINTS[9][0], SETUP_POINTS[9][1], SETUP_POINTS[9][2], SETUP_POINTS[9][1] + 10), + SETUP_POINTS[9][3] - screen.stringWidth(tempStr) / 2, tempStr); + + tempStr = Common::String::format("Portraits %s", SETUP_STRS0[people._portraitsOn]); + screen.makeButton(Common::Rect(SETUP_POINTS[10][0], SETUP_POINTS[10][1], SETUP_POINTS[10][2], SETUP_POINTS[10][1] + 10), + SETUP_POINTS[10][3] - screen.stringWidth(tempStr) / 2, tempStr); + tempStr = Common::String::format("Key Pad %s", _vm->_keyPadSpeed ? "Fast" : "Slow"); + + screen.makeButton(Common::Rect(SETUP_POINTS[11][0], SETUP_POINTS[11][1], SETUP_POINTS[11][2], SETUP_POINTS[11][1] + 10), + SETUP_POINTS[11][3] - screen.stringWidth(tempStr) / 2, tempStr); + + // Show the window immediately, or slide it on-screen + if (!flag) { + if (!ui._windowStyle) { + screen.slamRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + } else { + ui.summonWindow(true, CONTROLS_Y1); + } + + ui._windowOpen = true; + } else { + screen.slamRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + } +} + +/** + * Draws the buttons for the settings dialog + */ +int Settings::drawButtons(const Common::Point &pt, int _key) { + Events &events = *_vm->_events; + People &people = *_vm->_people; + Screen &screen = *_vm->_screen; + Sound &sound = *_vm->_sound; + UserInterface &ui = *_vm->_ui; + int found = -1; + byte color; + Common::String tempStr; + + for (int idx = 0; idx < 12; ++idx) { + if ((pt.x > SETUP_POINTS[idx][0] && pt.x < SETUP_POINTS[idx][2] && pt.y > SETUP_POINTS[idx][1] + && pt.y < (SETUP_POINTS[idx][1] + 10) && (events._released || events._released)) + || (_key == SETUP_NAMES[idx][0])) { + found = idx; + color = COMMAND_HIGHLIGHTED; + } else { + color = COMMAND_FOREGROUND; + } + + // Print the button text + switch (idx) { + case 1: + tempStr = Common::String::format("Music %s", SETUP_STRS0[sound._music]); + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); + break; + case 2: + tempStr = Common::String::format("Voices %s", SETUP_STRS0[sound._voices]); + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); + break; + case 3: + tempStr = Common::String::format("Sound Effects %s", SETUP_STRS0[sound._digitized]); + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); + break; + case 4: + tempStr = Common::String::format("Auto Help %s", SETUP_STRS2[ui._helpStyle]); + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); + break; + case 6: + tempStr = "Joystick Off"; + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), COMMAND_NULL, true, tempStr); + break; + case 7: + tempStr = "Calibrate Joystick"; + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), COMMAND_NULL, true, tempStr); + break; + case 8: + tempStr = Common::String::format("Fade %s", SETUP_STRS1[screen._fadeStyle]); + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); + break; + case 9: + tempStr = Common::String::format("Windows %s", SETUP_STRS3[ui._windowStyle]); + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); + break; + case 10: + tempStr = Common::String::format("Portraits %s", SETUP_STRS0[people._portraitsOn]); + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); + break; + case 11: + tempStr = Common::String::format("Key Pad %s", SETUP_STRS4[_vm->_keyPadSpeed]); + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); + break; + default: + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, SETUP_NAMES[idx]); + break; + } + } + + return found; +} + +} // End of namespace Sherlock diff --git a/engines/sherlock/settings.h b/engines/sherlock/settings.h new file mode 100644 index 0000000000..51157f4cae --- /dev/null +++ b/engines/sherlock/settings.h @@ -0,0 +1,45 @@ +/* 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 SHERLOCK_SETTINGS_H +#define SHERLOCK_SETTINGS_H + +#include "common/scummsys.h" + +namespace Sherlock { + +class SherlockEngine; + +class Settings { +private: + SherlockEngine *_vm; +public: + Settings(SherlockEngine *vm) : _vm(vm) {} + + void drawInteface(bool flag); + + int drawButtons(const Common::Point &pt, int key); +}; + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 21a53c32ff..313f035bd5 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -22,6 +22,7 @@ #include "sherlock/user_interface.h" #include "sherlock/sherlock.h" +#include "sherlock/settings.h" namespace Sherlock { @@ -53,23 +54,6 @@ const int INVENTORY_POINTS[8][3] = { { 285, 315, 294 } }; -const int SETUP_POINTS[12][4] = { - { 4, 154, 101, 53 }, // Exit - { 4, 165, 101, 53 }, // Music Toggle - { 219, 165, 316, 268 }, // Voice Toggle - { 103, 165, 217, 160 }, // Sound Effects Toggle - { 219, 154, 316, 268 }, // Help Button Left/Right - { 103, 154, 217, 160 }, // New Font Style - { 4, 187, 101, 53 }, // Joystick Toggle - { 103, 187, 217, 160 }, // Calibrate Joystick - { 219, 176, 316, 268 }, // Fade Style - { 103, 176, 217, 160 }, // Window Open Style - { 4, 176, 101, 53 }, // Portraits Toggle - { 219, 187, 316, 268 } // _key Pad Accel. Toggle -}; - - - const char COMMANDS[13] = "LMTPOCIUGJFS"; const char INVENTORY_COMMANDS[9] = { "ELUG-+,." }; const char *const PRESS_KEY_FOR_MORE = "Press any Key for More."; @@ -94,174 +78,6 @@ const char *const MUSE[] = { "Doors don't smoke" }; -const char *const SETUP_STRS0[2] = { "off", "on" }; -const char *const SETUP_STRS1[2] = { "Directly", "by Pixel" }; -const char *const SETUP_STRS2[2] = { "Left", "Right" }; -const char *const SETUP_STRS3[2] = { "Appear", "Slide" }; -const char *const SETUP_STRS4[2] = { "Slow", "Fast" }; -const char *const SETUP_STRS5[2] = { "Left", "Right" }; -const char *const SETUP_NAMES[12] = { - "Exit", "M", "V", "S", "B", "New Font Style", "J", "Calibrate Joystick", "F", "W", "P", "K" -}; - -/*----------------------------------------------------------------*/ - -/** - * Draws the interface for the settings window - */ -void Settings::drawInteface(bool flag) { - People &people = *_vm->_people; - Screen &screen = *_vm->_screen; - Sound &sound = *_vm->_sound; - UserInterface &ui = *_vm->_ui; - Common::String tempStr; - - if (!flag) { - screen._backBuffer1.fillRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y1 + 1), BORDER_COLOR); - screen._backBuffer1.fillRect(Common::Rect(0, CONTROLS_Y1 + 1, 2, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); - screen._backBuffer1.fillRect(Common::Rect(SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y1 + 1, SHERLOCK_SCREEN_WIDTH, - SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); - screen._backBuffer1.hLine(0, SHERLOCK_SCREEN_HEIGHT - 1, SHERLOCK_SCREEN_WIDTH - 1, BORDER_COLOR); - screen._backBuffer1.fillRect(Common::Rect(2, CONTROLS_Y1 + 1, SHERLOCK_SCREEN_WIDTH - 2, - SHERLOCK_SCREEN_HEIGHT - 2), INV_BACKGROUND); - } - - screen.makeButton(Common::Rect(SETUP_POINTS[0][0], SETUP_POINTS[0][1], SETUP_POINTS[0][2], SETUP_POINTS[0][1] + 10), - SETUP_POINTS[0][3] - screen.stringWidth("Exit") / 2, "Exit"); - - tempStr = Common::String::format("Music %s", SETUP_STRS0[sound._music]); - screen.makeButton(Common::Rect(SETUP_POINTS[1][0], SETUP_POINTS[1][1], SETUP_POINTS[1][2], SETUP_POINTS[1][1] + 10), - SETUP_POINTS[1][3] - screen.stringWidth(tempStr) / 2, tempStr); - - tempStr = Common::String::format("Voices %s", SETUP_STRS0[sound._voices]); - screen.makeButton(Common::Rect(SETUP_POINTS[2][0], SETUP_POINTS[2][1], SETUP_POINTS[2][2], SETUP_POINTS[2][1] + 10), - SETUP_POINTS[2][3] - screen.stringWidth(tempStr) / 2, tempStr); - - tempStr = Common::String::format("Sound Effects %s", SETUP_STRS0[sound._digitized]); - screen.makeButton(Common::Rect(SETUP_POINTS[3][0], SETUP_POINTS[3][1], SETUP_POINTS[3][2], SETUP_POINTS[3][1] + 10), - SETUP_POINTS[3][3] - screen.stringWidth(tempStr) / 2, tempStr); - - tempStr = Common::String::format("Auto Help %s", SETUP_STRS5[ui._helpStyle]); - screen.makeButton(Common::Rect(SETUP_POINTS[4][0], SETUP_POINTS[4][1], SETUP_POINTS[4][2], SETUP_POINTS[4][1] + 10), - SETUP_POINTS[4][3] - screen.stringWidth(tempStr) / 2, tempStr); - screen.makeButton(Common::Rect(SETUP_POINTS[5][0], SETUP_POINTS[5][1], SETUP_POINTS[5][2], SETUP_POINTS[5][1] + 10), - SETUP_POINTS[5][3] - screen.stringWidth("New Font Style") / 2, "New Font Style"); - - // WORKAROUND: We don't support the joystick in ScummVM, so draw the next two buttons as disabled - tempStr = "Joystick Off"; - screen.makeButton(Common::Rect(SETUP_POINTS[6][0], SETUP_POINTS[6][1], SETUP_POINTS[6][2], SETUP_POINTS[6][1] + 10), - SETUP_POINTS[6][3] - screen.stringWidth(tempStr) / 2, tempStr); - screen.buttonPrint(Common::Point(SETUP_POINTS[6][3], SETUP_POINTS[6][1]), COMMAND_NULL, false, tempStr); - - tempStr = "Calibrate Joystick"; - screen.makeButton(Common::Rect(SETUP_POINTS[7][0], SETUP_POINTS[7][1], SETUP_POINTS[7][2], SETUP_POINTS[7][1] + 10), - SETUP_POINTS[7][3] - screen.stringWidth(tempStr) / 2, tempStr); - screen.buttonPrint(Common::Point(SETUP_POINTS[7][3], SETUP_POINTS[7][1]), COMMAND_NULL, false, tempStr); - - tempStr = Common::String::format("Fade %s", screen._fadeStyle ? "by Pixel" : "Directly"); - screen.makeButton(Common::Rect(SETUP_POINTS[8][0], SETUP_POINTS[8][1], SETUP_POINTS[8][2], SETUP_POINTS[8][1] + 10), - SETUP_POINTS[8][3] - screen.stringWidth(tempStr) / 2, tempStr); - - tempStr = Common::String::format("Windows %s", ui._windowStyle ? "Slide" : "Appear"); - screen.makeButton(Common::Rect(SETUP_POINTS[9][0], SETUP_POINTS[9][1], SETUP_POINTS[9][2], SETUP_POINTS[9][1] + 10), - SETUP_POINTS[9][3] - screen.stringWidth(tempStr) / 2, tempStr); - - tempStr = Common::String::format("Portraits %s", SETUP_STRS0[people._portraitsOn]); - screen.makeButton(Common::Rect(SETUP_POINTS[10][0], SETUP_POINTS[10][1], SETUP_POINTS[10][2], SETUP_POINTS[10][1] + 10), - SETUP_POINTS[10][3] - screen.stringWidth(tempStr) / 2, tempStr); - tempStr = Common::String::format("Key Pad %s", _vm->_keyPadSpeed ? "Fast" : "Slow"); - - screen.makeButton(Common::Rect(SETUP_POINTS[11][0], SETUP_POINTS[11][1], SETUP_POINTS[11][2], SETUP_POINTS[11][1] + 10), - SETUP_POINTS[11][3] - screen.stringWidth(tempStr) / 2, tempStr); - - // Show the window immediately, or slide it on-screen - if (!flag) { - if (!ui._windowStyle) { - screen.slamRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); - } else { - ui.summonWindow(true, CONTROLS_Y1); - } - - ui._windowOpen = true; - } else { - screen.slamRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); - } -} - -/** - * Draws the buttons for the settings dialog - */ -int Settings::drawButtons(const Common::Point &pt, int _key) { - Events &events = *_vm->_events; - People &people = *_vm->_people; - Screen &screen = *_vm->_screen; - Sound &sound = *_vm->_sound; - UserInterface &ui = *_vm->_ui; - int found = -1; - byte color; - Common::String tempStr; - - for (int idx = 0; idx < 12; ++idx) { - if ((pt.x > SETUP_POINTS[idx][0] && pt.x < SETUP_POINTS[idx][2] && pt.y > SETUP_POINTS[idx][1] - && pt.y < (SETUP_POINTS[idx][1] + 10) && (events._released || events._released)) - || (_key == SETUP_NAMES[idx][0])) { - found = idx; - color = COMMAND_HIGHLIGHTED; - } else { - color = COMMAND_FOREGROUND; - } - - // Print the button text - switch (idx) { - case 1: - tempStr = Common::String::format("Music %s", SETUP_STRS0[sound._music]); - screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); - break; - case 2: - tempStr = Common::String::format("Voices %s", SETUP_STRS0[sound._voices]); - screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); - break; - case 3: - tempStr = Common::String::format("Sound Effects %s", SETUP_STRS0[sound._digitized]); - screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); - break; - case 4: - tempStr = Common::String::format("Auto Help %s", SETUP_STRS2[ui._helpStyle]); - screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); - break; - case 6: - tempStr = "Joystick Off"; - screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), COMMAND_NULL, true, tempStr); - break; - case 7: - tempStr = "Calibrate Joystick"; - screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), COMMAND_NULL, true, tempStr); - break; - case 8: - tempStr = Common::String::format("Fade %s", SETUP_STRS1[screen._fadeStyle]); - screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); - break; - case 9: - tempStr = Common::String::format("Windows %s", SETUP_STRS3[ui._windowStyle]); - screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); - break; - case 10: - tempStr = Common::String::format("Portraits %s", SETUP_STRS0[people._portraitsOn]); - screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); - break; - case 11: - tempStr = Common::String::format("Key Pad %s", SETUP_STRS4[_vm->_keyPadSpeed]); - screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); - break; - default: - screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, SETUP_NAMES[idx]); - break; - } - } - - return found; -} - /*----------------------------------------------------------------*/ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index ac2c16d7c2..4e8753199b 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -63,17 +63,6 @@ class Inventory; class Talk; class UserInterface; -class Settings { -private: - SherlockEngine *_vm; -public: - Settings(SherlockEngine *vm) : _vm(vm) {} - - void drawInteface(bool flag); - - int drawButtons(const Common::Point &pt, int key); -}; - class UserInterface { friend class Inventory; friend class Settings; -- cgit v1.2.3 From 86dab70eae4791b84ca3891cad7db70a9683679a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 18:34:51 -1000 Subject: SHERLOCK: Remove unused key pad speed field --- engines/sherlock/settings.cpp | 7 ++++--- engines/sherlock/sherlock.cpp | 1 - engines/sherlock/sherlock.h | 1 - engines/sherlock/user_interface.cpp | 7 ------- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/engines/sherlock/settings.cpp b/engines/sherlock/settings.cpp index fb7730fc1d..769c2c82e3 100644 --- a/engines/sherlock/settings.cpp +++ b/engines/sherlock/settings.cpp @@ -115,10 +115,11 @@ void Settings::drawInteface(bool flag) { tempStr = Common::String::format("Portraits %s", SETUP_STRS0[people._portraitsOn]); screen.makeButton(Common::Rect(SETUP_POINTS[10][0], SETUP_POINTS[10][1], SETUP_POINTS[10][2], SETUP_POINTS[10][1] + 10), SETUP_POINTS[10][3] - screen.stringWidth(tempStr) / 2, tempStr); - tempStr = Common::String::format("Key Pad %s", _vm->_keyPadSpeed ? "Fast" : "Slow"); + tempStr = "Key Pad Slow"; screen.makeButton(Common::Rect(SETUP_POINTS[11][0], SETUP_POINTS[11][1], SETUP_POINTS[11][2], SETUP_POINTS[11][1] + 10), SETUP_POINTS[11][3] - screen.stringWidth(tempStr) / 2, tempStr); + screen.buttonPrint(Common::Point(SETUP_POINTS[11][3], SETUP_POINTS[11][1]), COMMAND_NULL, false, tempStr); // Show the window immediately, or slide it on-screen if (!flag) { @@ -196,8 +197,8 @@ int Settings::drawButtons(const Common::Point &pt, int _key) { screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); break; case 11: - tempStr = Common::String::format("Key Pad %s", SETUP_STRS4[_vm->_keyPadSpeed]); - screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); + tempStr = "Key Pad Slow"; + screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), COMMAND_NULL, true, tempStr); break; default: screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, SETUP_NAMES[idx]); diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 3ab2caabc4..0282d3e5f0 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -47,7 +47,6 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _ui = nullptr; _useEpilogue2 = false; _loadingSavedGame = false; - _keyPadSpeed = 0; _loadGameSlot = -1; _canLoadSave = false; } diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 02e2e99229..dfaaa70806 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -106,7 +106,6 @@ public: Common::String _titleOverride; bool _useEpilogue2; bool _loadingSavedGame; - int _keyPadSpeed; int _loadGameSlot; bool _canLoadSave; public: diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 313f035bd5..cab0fb0ad8 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1968,13 +1968,6 @@ void UserInterface::doControls() { updateConfig = true; settings.drawInteface(true); } - - if ((found == 11 && events._released) || _key == 'K') { - // Toggle keypad acceleration speed - _vm->_keyPadSpeed ^= 1; - updateConfig = true; - settings.drawInteface(true); - } } while (!_vm->shouldQuit()); banishWindow(); -- cgit v1.2.3 From 850bd739687129542c37db0beebd17369c71ed15 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 18:47:13 -1000 Subject: SHERLOCK: Move Settings dialog event handling into Settings class --- engines/sherlock/settings.cpp | 138 ++++++++++++++++++++++++++++++++++ engines/sherlock/settings.h | 5 +- engines/sherlock/sherlock.cpp | 3 + engines/sherlock/user_interface.cpp | 146 +----------------------------------- engines/sherlock/user_interface.h | 2 - 5 files changed, 146 insertions(+), 148 deletions(-) diff --git a/engines/sherlock/settings.cpp b/engines/sherlock/settings.cpp index 769c2c82e3..aeeb92d3c1 100644 --- a/engines/sherlock/settings.cpp +++ b/engines/sherlock/settings.cpp @@ -209,4 +209,142 @@ int Settings::drawButtons(const Common::Point &pt, int _key) { return found; } + +/** +* Handles input when the settings window is being shown +* @remarks Whilst this would in theory be better in the Journal class, since it displays in +* the user interface, it uses so many internal UI fields, that it sort of made some sense +* to put it in the UserInterface class. +*/ +void Settings::show(SherlockEngine *vm) { + Events &events = *vm->_events; + People &people = *vm->_people; + Scene &scene = *vm->_scene; + Screen &screen = *vm->_screen; + Sound &sound = *vm->_sound; + Talk &talk = *vm->_talk; + UserInterface &ui = *vm->_ui; + int found; + bool updateConfig = false; + + Settings settings(vm); + settings.drawInteface(false); + + do { + if (ui._menuCounter) + ui.whileMenuCounter(); + + found = -1; + ui._key = -1; + + scene.doBgAnim(); + if (talk._talkToAbort) + return; + + events.setButtonState(); + Common::Point pt = events.mousePos(); + + if (events._pressed || events._released || events.kbHit()) { + ui.clearInfo(); + ui._key = -1; + + if (events.kbHit()) { + Common::KeyState keyState = events.getKey(); + ui._key = toupper(keyState.keycode); + + if (ui._key == Common::KEYCODE_RETURN || ui._key == Common::KEYCODE_SPACE) { + events._pressed = false; + events._oldButtons = 0; + ui._keycode = Common::KEYCODE_INVALID; + events._released = true; + } + } + + // Handle highlighting button under mouse + found = settings.drawButtons(pt, ui._key); + } + + if ((found == 0 && events._released) || (ui._key == 'E' || ui._key == Common::KEYCODE_ESCAPE)) + // Exit + break; + + if ((found == 1 && events._released) || ui._key == 'M') { + // Toggle music + if (sound._music) { + sound.stopSound(); + sound._music = false; + } + else { + sound._music = true; + sound.startSong(); + } + + updateConfig = true; + settings.drawInteface(true); + } + + if ((found == 2 && events._released) || ui._key == 'V') { + sound._voices = !sound._voices; + updateConfig = true; + settings.drawInteface(true); + } + + if ((found == 3 && events._released) || ui._key == 'S') { + // Toggle sound effects + sound._digitized = !sound._digitized; + updateConfig = true; + settings.drawInteface(true); + } + + if ((found == 4 && events._released) || ui._key == 'A') { + // Help button style + ui._helpStyle ^= 1; + updateConfig = true; + settings.drawInteface(true); + } + + if ((found == 5 && events._released) || ui._key == 'N') { + // New font style + int fontNum = screen.fontNumber() + 1; + if (fontNum == 3) + fontNum = 0; + + screen.setFont(fontNum); + updateConfig = true; + settings.drawInteface(true); + } + + if ((found == 8 && events._released) || ui._key == 'F') { + // Toggle fade style + screen._fadeStyle = !screen._fadeStyle; + updateConfig = true; + settings.drawInteface(true); + } + + if ((found == 9 && events._released) || ui._key == 'W') { + // Window style + ui._windowStyle ^= 1; + updateConfig = true; + settings.drawInteface(true); + } + + if ((found == 10 && events._released) || ui._key == 'P') { + // Toggle portraits being shown + people._portraitsOn = !people._portraitsOn; + updateConfig = true; + settings.drawInteface(true); + } + } while (!vm->shouldQuit()); + + ui.banishWindow(); + + if (updateConfig) + vm->saveConfig(); + + ui._keycode = Common::KEYCODE_INVALID; + ui._keyboardInput = false; + ui._windowBounds.top = CONTROLS_Y1; + ui._key = -1; +} + } // End of namespace Sherlock diff --git a/engines/sherlock/settings.h b/engines/sherlock/settings.h index 51157f4cae..90928452c4 100644 --- a/engines/sherlock/settings.h +++ b/engines/sherlock/settings.h @@ -28,16 +28,19 @@ namespace Sherlock { class SherlockEngine; +class UserInterface; class Settings { private: SherlockEngine *_vm; -public: + Settings(SherlockEngine *vm) : _vm(vm) {} void drawInteface(bool flag); int drawButtons(const Common::Point &pt, int key); +public: + static void show(SherlockEngine *vm); }; } // End of namespace Sherlock diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 0282d3e5f0..f546e0d878 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -214,6 +214,8 @@ void SherlockEngine::loadConfig() { // Load other settings if (ConfMan.hasKey("font")) _screen->setFont(ConfMan.getInt("font")); + if (ConfMan.hasKey("fade_style")) + _screen->_fadeStyle = ConfMan.getBool("fade_style"); if (ConfMan.hasKey("help_style")) _ui->_helpStyle = ConfMan.getInt("help_style"); if (ConfMan.hasKey("window_style")) @@ -231,6 +233,7 @@ void SherlockEngine::saveConfig() { ConfMan.setBool("speech_mute", _sound->_voices); ConfMan.setInt("font", _screen->fontNumber()); + ConfMan.setBool("fade_style", _screen->_fadeStyle); ConfMan.setInt("help_style", _ui->_helpStyle); ConfMan.setInt("window_style", _ui->_windowStyle); ConfMan.setBool("portraits_on", _people->_portraitsOn); diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index cab0fb0ad8..73058e8fd8 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1440,7 +1440,7 @@ void UserInterface::doMainControl() { case 'S': pushButton(11); _menuMode = SETUP_MODE; - doControls(); + Settings::show(_vm); break; default: break; @@ -1837,150 +1837,6 @@ void UserInterface::journalControl() { screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } -/** - * Handles input when the settings window is being shown - * @remarks Whilst this would in theory be better in the Journal class, since it displays in - * the user interface, it uses so many internal UI fields, that it sort of made some sense - * to put it in the UserInterface class. - */ -void UserInterface::doControls() { - Events &events = *_vm->_events; - People &people = *_vm->_people; - Scene &scene = *_vm->_scene; - Screen &screen = *_vm->_screen; - Sound &sound = *_vm->_sound; - Talk &talk = *_vm->_talk; - UserInterface &ui = *_vm->_ui; - int found; - bool updateConfig = false; - - Settings settings(_vm); - settings.drawInteface(false); - - do { - if (_menuCounter) - whileMenuCounter(); - - found = -1; - _key = -1; - - scene.doBgAnim(); - if (talk._talkToAbort) - return; - - events.setButtonState(); - Common::Point pt = events.mousePos(); - - if (events._pressed || events._released || events.kbHit()) { - clearInfo(); - _key = -1; - - if (events.kbHit()) { - Common::KeyState keyState = events.getKey(); - _key = toupper(keyState.keycode); - - if (_key == Common::KEYCODE_RETURN || _key == Common::KEYCODE_SPACE) { - events._pressed = false; - events._oldButtons = 0; - _keycode = Common::KEYCODE_INVALID; - events._released = true; - } - } - - // Handle highlighting button under mouse - found = settings.drawButtons(pt, _key); - } - - if ((found == 0 && events._released) || (_key == 'E' || _key == Common::KEYCODE_ESCAPE)) - // Exit - break; - - if ((found == 1 && events._released) || _key == 'M') { - // Toggle music - if (sound._music) { - sound.stopSound(); - sound._music = false; - } else { - sound._music = true; - sound.startSong(); - } - - updateConfig = true; - settings.drawInteface(true); - } - - if ((found == 2 && events._released) || _key == 'V') { - sound._voices = !sound._voices; - updateConfig = true; - settings.drawInteface(true); - } - - if ((found == 3 && events._released) || _key == 'S') { - // Toggle sound effects - sound._digitized = !sound._digitized; - updateConfig = true; - settings.drawInteface(true); - } - - if ((found == 4 && events._released) || _key == 'A') { - // Help button style - ui._helpStyle ^= 1; - updateConfig = true; - settings.drawInteface(true); - } - - if ((found == 5 && events._released) || _key == 'N') { - // New font style - int fontNum = screen.fontNumber() + 1; - if (fontNum == 3) - fontNum = 0; - - screen.setFont(fontNum); - updateConfig = true; - settings.drawInteface(true); - } - - if ((found == 6 && events._released) || _key == 'J') { - // Toggle joystick - not implemented under ScummVM - } - - if ((found == 7 && events._released) || _key == 'C') { - // Calibrate joystick - No implementation in ScummVM - } - - if ((found == 8 && events._released) || _key == 'F') { - // Toggle fade style - screen._fadeStyle = !screen._fadeStyle; - updateConfig = true; - settings.drawInteface(true); - } - - if ((found == 9 && events._released) || _key == 'W') { - // Window style - ui._windowStyle ^= 1; - updateConfig = true; - settings.drawInteface(true); - } - - if ((found == 10 && events._released) || _key == 'P') { - // Toggle portraits being shown - people._portraitsOn = !people._portraitsOn; - updateConfig = true; - settings.drawInteface(true); - } - } while (!_vm->shouldQuit()); - - banishWindow(); - - if (updateConfig) - _vm->saveConfig(); - - _keycode = Common::KEYCODE_INVALID; - _keyboardInput = false; - _windowBounds.top = CONTROLS_Y1; - _key = -1; -} - /** * Print the description of an object */ diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index 4e8753199b..89a33801dd 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -111,8 +111,6 @@ private: void doTalkControl(); void journalControl(); - void doControls(); - void checkUseAction(const UseType *use, const Common::String &invName, const char *const messages[], int objNum, int giveMode); void checkAction(ActionType &action, const char *const messages[], int objNum); -- cgit v1.2.3 From 7cf9fcd44e58a5a4b1988bb5ca6ec6862170c3d8 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 19:13:53 -1000 Subject: SHERLOCK: Change _helpStyle from int to bool --- engines/sherlock/settings.cpp | 2 +- engines/sherlock/sherlock.cpp | 4 ++-- engines/sherlock/user_interface.cpp | 2 +- engines/sherlock/user_interface.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/engines/sherlock/settings.cpp b/engines/sherlock/settings.cpp index aeeb92d3c1..1673eca389 100644 --- a/engines/sherlock/settings.cpp +++ b/engines/sherlock/settings.cpp @@ -298,7 +298,7 @@ void Settings::show(SherlockEngine *vm) { if ((found == 4 && events._released) || ui._key == 'A') { // Help button style - ui._helpStyle ^= 1; + ui._helpStyle = !ui._helpStyle; updateConfig = true; settings.drawInteface(true); } diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index f546e0d878..c33ecb6d49 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -217,7 +217,7 @@ void SherlockEngine::loadConfig() { if (ConfMan.hasKey("fade_style")) _screen->_fadeStyle = ConfMan.getBool("fade_style"); if (ConfMan.hasKey("help_style")) - _ui->_helpStyle = ConfMan.getInt("help_style"); + _ui->_helpStyle = ConfMan.getBool("help_style"); if (ConfMan.hasKey("window_style")) _ui->_windowStyle = ConfMan.getInt("window_style"); if (ConfMan.hasKey("portraits_on")) @@ -234,7 +234,7 @@ void SherlockEngine::saveConfig() { ConfMan.setInt("font", _screen->fontNumber()); ConfMan.setBool("fade_style", _screen->_fadeStyle); - ConfMan.setInt("help_style", _ui->_helpStyle); + ConfMan.setBool("help_style", _ui->_helpStyle); ConfMan.setInt("window_style", _ui->_windowStyle); ConfMan.setBool("portraits_on", _people->_portraitsOn); diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 73058e8fd8..d75e0770b9 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -86,7 +86,7 @@ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { _bgFound = 0; _oldBgFound = -1; _keycode = Common::KEYCODE_INVALID; - _helpStyle = 0; + _helpStyle = false; _menuCounter = 0; _menuMode = STD_MODE; _help = _oldHelp = 0; diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index 89a33801dd..a0b854af36 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -123,7 +123,7 @@ public: int _invLookFlag; int _temp1; int _windowStyle; - int _helpStyle; + bool _helpStyle; public: UserInterface(SherlockEngine *vm); ~UserInterface(); -- cgit v1.2.3 From 8fab80ce4750ad65b6e289614034478cebdf7854 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 20:31:43 -1000 Subject: SHERLOCK: Tweak doBgAnim delays to better match original game --- engines/sherlock/scene.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index e69fb49766..ab57e9cfd2 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -1387,9 +1387,9 @@ void Scene::doBgAnim() { } _restoreFlag = true; - - events.wait(1); _doBgAnimDone = true; + + events.wait(3); screen.resetDisplayBounds(); // Check if the method was called for calling a portrait, and a talk was -- cgit v1.2.3 From 90b35d2381488daa4cf54101ebd8f4b9e8ca0083 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 1 May 2015 20:33:56 -1000 Subject: SHERLOCK: Allow fast quitting when randomTransition in progress --- engines/sherlock/screen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index d170772c98..1f56261150 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -216,7 +216,7 @@ void Screen::randomTransition() { const int TRANSITION_MULTIPLIER = 0x15a4e35; _dirtyRects.clear(); - for (int idx = 0; idx <= 65535; ++idx) { + for (int idx = 0; idx <= 65535 && !_vm->shouldQuit(); ++idx) { _transitionSeed = _transitionSeed * TRANSITION_MULTIPLIER + 1; int offset = _transitionSeed & 65535; -- cgit v1.2.3 From dceff029220aff2efcb7a533d2403c90b5651870 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 2 May 2015 13:53:20 -1000 Subject: SHERLOCK: Fix trying to enter theatre without talking to Lestrade --- engines/sherlock/user_interface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index d75e0770b9..93dd03316d 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1469,7 +1469,7 @@ void UserInterface::doMiscControl(int allowed) { switch (allowed) { case ALLOW_OPEN: checkAction(obj._aOpen, MOPEN, _temp); - if (_menuMode && !talk._talkToAbort) { + if (_menuMode != TALK_MODE && !talk._talkToAbort) { _menuMode = STD_MODE; restoreButton(OPEN_MODE - 1); _key = _oldKey = -1; -- cgit v1.2.3 From eb4757d6e31171bde9b03fa44c20ab490639b5c0 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 2 May 2015 14:34:49 -1000 Subject: SHERLOCK: Fix original game bug when testing powdery substance --- engines/sherlock/talk.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index d05c09ab38..9af8a29c1e 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -433,6 +433,12 @@ void Talk::talkTo(const Common::String &filename) { // previous script can continue popStack(); + if (_vm->getGameID() == GType_SerratedScalpel && filename == "Tube59c") { + // WORKAROUND: Original game bug causes the results of testing the powdery substance + // to disappear too quickly. Introduce a delay to allow it to be properly displayed + ui._menuCounter = 30; + } + events.setCursor(ARROW); } -- cgit v1.2.3 From 9ff445497fe53b72193dcf944b54091080c90964 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 2 May 2015 16:29:08 -1000 Subject: SHERLOCK: Properly close door when entering Sarah's flat --- engines/sherlock/objects.cpp | 2 +- engines/sherlock/scene.cpp | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index fa5dfee26c..6f4795de7e 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -728,7 +728,7 @@ bool Object::checkEndOfSequence() { // Save details before shape is removed _delta.x = _imageFrame->_frame.w; _delta.y = _imageFrame->_frame.h; - _position = _imageFrame->_offset; + _position += _imageFrame->_offset; // Free the images delete _images; diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index ab57e9cfd2..2c5859024c 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -931,7 +931,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) { cObj._frameNumber = -1; cObj._sequenceNumber = cAnimNum; cObj._oldPosition = Common::Point(0, 0); - cObj._oldPosition = Common::Point(0, 0); + cObj._oldSize = Common::Point(0, 0); cObj._goto = Common::Point(0, 0); cObj._status = 0; cObj._misc = 0; @@ -1050,6 +1050,10 @@ int Scene::startCAnim(int cAnimNum, int playRate) { cObj.checkObject(); for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if (&_canimShapes[idx] == &cObj) { + // Do a final call to doBgAnim to erase the anim shape before it's erased + doBgAnim(); + + // Remove the completed sprite from the animation shapes array _canimShapes.remove_at(idx); break; } @@ -1372,7 +1376,7 @@ void Scene::doBgAnim() { } } - for (int idx = _canimShapes.size() - 1; idx >= 0; --idx) { + for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; if (o._type == REMOVE) { if (_goToScene == -1) -- cgit v1.2.3 From f97e550d8631bc1821da1c126ae545db15769c9c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 2 May 2015 17:48:07 -1000 Subject: SHERLOCK: Don't mark leaving scene as visited during savegame loads --- engines/sherlock/saveload.cpp | 1 - engines/sherlock/scene.cpp | 11 +++++++---- engines/sherlock/scene.h | 1 + engines/sherlock/sherlock.cpp | 2 -- engines/sherlock/sherlock.h | 1 - 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index 86a4e8417a..71e21618ae 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -388,7 +388,6 @@ void SaveManager::synchronize(Common::Serializer &s) { if (screen.fontNumber() != oldFont) journal.resetPosition(); - _vm->_loadingSavedGame = true; _justLoaded = true; } diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 2c5859024c..e3c1799d66 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -88,6 +88,7 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { Common::fill(&_sceneStats[idx][0], &_sceneStats[idx][65], false); _currentScene = -1; _goToScene = -1; + _loadingSavedGame = false; _changes = false; _keyboardInput = 0; _walkedInScene = false; @@ -162,10 +163,10 @@ void Scene::freeScene() { _vm->_sound->freeSong(); _vm->_sound->freeLoadedSounds(); - if (!_vm->_loadingSavedGame) + if (!_loadingSavedGame) saveSceneStatus(); else - _vm->_loadingSavedGame = false; + _loadingSavedGame = false; _sequenceBuffer.clear(); _descText.clear(); @@ -1494,10 +1495,12 @@ void Scene::synchronize(Common::Serializer &s) { if (s.isSaving()) saveSceneStatus(); - if (s.isSaving()) + if (s.isSaving()) { s.syncAsSint16LE(_currentScene); - else + } else { s.syncAsSint16LE(_goToScene); + _loadingSavedGame = true; + } for (int sceneNum = 0; sceneNum < SCENES_COUNT; ++sceneNum) { for (int flag = 0; flag < 65; ++flag) { diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 4fb7ac228a..7ee7db1119 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -89,6 +89,7 @@ private: Common::String _rrmName; int _selector; bool _lookHelp; + bool _loadingSavedGame; bool loadScene(const Common::String &filename); diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index c33ecb6d49..b8948f99d8 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -46,7 +46,6 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _talk = nullptr; _ui = nullptr; _useEpilogue2 = false; - _loadingSavedGame = false; _loadGameSlot = -1; _canLoadSave = false; } @@ -164,7 +163,6 @@ void SherlockEngine::sceneLoop() { } } - _scene->freeScene(); _people->freeWalk(); } diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index dfaaa70806..95fe514e0c 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -105,7 +105,6 @@ public: Common::String _soundOverride; Common::String _titleOverride; bool _useEpilogue2; - bool _loadingSavedGame; int _loadGameSlot; bool _canLoadSave; public: -- cgit v1.2.3 From 0a2c50deb5c61500410a91556ed5e3ceb0cc9742 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 2 May 2015 18:15:24 -1000 Subject: SHERLOCK: Revised door close fix due to new bug when entering morgue --- engines/sherlock/scene.cpp | 31 +++++++++++++++++-------------- engines/sherlock/scene.h | 7 ++++++- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index e3c1799d66..6e7f628616 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -83,6 +83,17 @@ void SceneSound::synchronize(Common::SeekableReadStream &s) { /*----------------------------------------------------------------*/ +int ObjectArray::indexOf(const Object &obj) const { + for (uint idx = 0; idx < size(); ++idx) { + if (&(*this)[idx] == &obj) + return idx; + } + + return -1; +} + +/*----------------------------------------------------------------*/ + Scene::Scene(SherlockEngine *vm): _vm(vm) { for (int idx = 0; idx < SCENES_COUNT; ++idx) Common::fill(&_sceneStats[idx][0], &_sceneStats[idx][65], false); @@ -1047,18 +1058,9 @@ int Scene::startCAnim(int cAnimNum, int playRate) { if (cObj._frameNumber <= 26) gotoCode = cObj._sequences[cObj._frameNumber + 3]; - // Set canim to REMOVE type and free memory - cObj.checkObject(); - for (uint idx = 0; idx < _canimShapes.size(); ++idx) { - if (&_canimShapes[idx] == &cObj) { - // Do a final call to doBgAnim to erase the anim shape before it's erased - doBgAnim(); - - // Remove the completed sprite from the animation shapes array - _canimShapes.remove_at(idx); - break; - } - } + // Unless anim shape has already been freed, set it to REMOVE so doBgAnim can free it + if (_canimShapes.indexOf(cObj) != -1) + cObj.checkObject(); if (gotoCode > 0 && !talk._talkToAbort) { _goToScene = gotoCode; @@ -1377,13 +1379,14 @@ void Scene::doBgAnim() { } } - for (uint idx = 0; idx < _canimShapes.size(); ++idx) { + for (int idx = _canimShapes.size() - 1; idx >= 0; --idx) { Object &o = _canimShapes[idx]; if (o._type == REMOVE) { if (_goToScene == -1) screen.slamArea(o._position.x, o._position.y, o._delta.x, o._delta.y); - _canimShapes[idx]._type = INVALID; + // Shape for an animation is no longer needed, so remove it completely + _canimShapes.remove_at(idx); } else if (o._type == ACTIVE_BG_SHAPE) { screen.flushImage(o._imageFrame, o._position, &o._oldPosition.x, &o._oldPosition.y, &o._oldSize.x, &o._oldSize.y); diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 7ee7db1119..c2cca8bad2 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -83,6 +83,11 @@ struct SceneSound { void synchronize(Common::SeekableReadStream &s); }; +class ObjectArray: public Common::Array { +public: + int indexOf(const Object &obj) const; +}; + class Scene { private: SherlockEngine *_vm; @@ -127,7 +132,7 @@ public: Common::Array _exits; SceneEntry _entrance; Common::Array _sounds; - Common::Array _canimShapes; + ObjectArray _canimShapes; bool _restoreFlag; int _animating; bool _doBgAnimDone; -- cgit v1.2.3 From c5d5694883a48974cf85f5d2a854d3a7c5d8b1d4 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 2 May 2015 18:51:13 -1000 Subject: SHERLOCK: Fix gfx glitch when returning to morgue for a second time --- engines/sherlock/scene.cpp | 5 +++++ engines/sherlock/sherlock.cpp | 1 + 2 files changed, 6 insertions(+) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 6e7f628616..8a47707aea 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -169,6 +169,9 @@ void Scene::selectScene() { * Fres all the graphics and other dynamically allocated data for the scene */ void Scene::freeScene() { + if (_currentScene == -1) + return; + _vm->_talk->freeTalkVars(); _vm->_inventory->freeInv(); _vm->_sound->freeSong(); @@ -190,6 +193,8 @@ void Scene::freeScene() { for (uint idx = 0; idx < _images.size(); ++idx) delete _images[idx]._images; _images.clear(); + + _currentScene = -1; } /** diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index b8948f99d8..8b25615792 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -163,6 +163,7 @@ void SherlockEngine::sceneLoop() { } } + _scene->freeScene(); _people->freeWalk(); } -- cgit v1.2.3 From 32d46dc00ab82bebc46f57dba8eb1be7e226d6f2 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 3 May 2015 18:17:50 -1000 Subject: SHERLOCK: Fix crash when moving crates --- engines/sherlock/talk.cpp | 8 ++++++++ engines/sherlock/talk.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 9af8a29c1e..953f884625 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -26,6 +26,14 @@ namespace Sherlock { +SequenceEntry::SequenceEntry() { + _objNum = 0; + _frameNumber = 0; + _seqTo = 0; +} + +/*----------------------------------------------------------------*/ + /** * Load the data for a single statement within a talk file */ diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index d545d31351..f96c3176d2 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -77,6 +77,8 @@ struct SequenceEntry { Common::Array _sequences; int _frameNumber; int _seqTo; + + SequenceEntry(); }; struct ScriptStackEntry { -- cgit v1.2.3 From 0554e893cef70dc7fd4bbdad8227d17b14d076d1 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 3 May 2015 18:19:12 -1000 Subject: SHERLOCK: Fix picking up knife in taxidermy --- engines/sherlock/talk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 953f884625..11385ca978 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -184,7 +184,7 @@ void Talk::talkTo(const Common::String &filename) { if (_savedSequences.size() > 0) { for (uint idx = 0; idx < _savedSequences.size(); ++idx) { SequenceEntry &ss = _savedSequences[idx]; - for (uint idx2 = 0; idx2 < _savedSequences.size(); ++idx2) + for (uint idx2 = 0; idx2 < ss._sequences.size(); ++idx2) scene._bgShapes[ss._objNum]._sequences[idx2] = ss._sequences[idx2]; // Reset the object's frame to the beginning of the sequence -- cgit v1.2.3 From 8a9467b09aab38649a891934c17a7b15608ddf0a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 4 May 2015 13:22:43 -1000 Subject: SHERLOCK: Check _talkToAbort after calling pickupObject --- engines/sherlock/user_interface.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 93dd03316d..d40e1cced1 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1508,6 +1508,7 @@ void UserInterface::doMiscControl(int allowed) { void UserInterface::doPickControl() { Events &events = *_vm->_events; Scene &scene = *_vm->_scene; + Talk &talk = *_vm->_talk; if (events._released) { if ((_temp = _bgFound) != -1) { @@ -1517,7 +1518,7 @@ void UserInterface::doPickControl() { if (_bgFound < 1000) { scene._bgShapes[_bgFound].pickUpObject(MPICK); - if (_menuMode != TALK_MODE) { + if (!talk._talkToAbort && _menuMode != TALK_MODE) { _key = _oldKey = -1; _menuMode = STD_MODE; restoreButton(PICKUP_MODE - 1); -- cgit v1.2.3 From 034e1384aad1ed91bb8879cded8e0247ae6f9000 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 4 May 2015 13:41:01 -1000 Subject: SHERLOCK: Fix picking up Sarah's effects in Morgue --- engines/sherlock/scene.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 8a47707aea..857dff4951 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -1386,7 +1386,11 @@ void Scene::doBgAnim() { for (int idx = _canimShapes.size() - 1; idx >= 0; --idx) { Object &o = _canimShapes[idx]; - if (o._type == REMOVE) { + + if (o._type == INVALID) { + // Anim shape was invalidated by checkEndOfSequence, so at this point we can remove it + _canimShapes.remove_at(idx); + } else if (o._type == REMOVE) { if (_goToScene == -1) screen.slamArea(o._position.x, o._position.y, o._delta.x, o._delta.y); -- cgit v1.2.3 From 0c12b85d4b67b022b227774db0cd531cf20d528e Mon Sep 17 00:00:00 2001 From: Strangerke Date: Tue, 5 May 2015 07:00:24 +0200 Subject: SHERLOCK: Fix checkForSoundFrames, add some warning TODOs --- engines/sherlock/animation.cpp | 2 +- engines/sherlock/sherlock.h | 1 + engines/sherlock/sound.cpp | 32 +++++++++++++++++++++++--------- engines/sherlock/sound.h | 3 ++- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index aea4793a76..b1ec6590b1 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -182,7 +182,7 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade, const int *Animation::checkForSoundFrames(const Common::String &filename) { const int *frames = &NO_FRAMES; - if (!_vm->_soundOverride.empty()) { + if (_vm->_soundOverride.empty()) { for (int idx = 0; idx < PROLOGUE_NAMES_COUNT; ++idx) { if (!scumm_stricmp(filename.c_str(), PROLOGUE_NAMES[idx])) { frames = &PROLOGUE_FRAMES[idx][0]; diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 95fe514e0c..06d38cbf89 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -27,6 +27,7 @@ #include "common/array.h" #include "common/endian.h" #include "common/hash-str.h" +#include "common/serializer.h" #include "common/random.h" #include "common/savefile.h" #include "common/util.h" diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index e66f82e5c4..1ee9535f31 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -20,6 +20,7 @@ * */ +#include "sherlock/sherlock.h" #include "sherlock/sound.h" #include "common/config-manager.h" @@ -29,12 +30,14 @@ Sound::Sound(SherlockEngine *vm): _vm(vm) { _digitized = false; _music = false; _voices = 0; - _soundOn = false; - _musicOn = false; - _speechOn = false; _playingEpilogue = false; _diskSoundPlaying = false; - _soundIsOn = nullptr; + _soundPlaying = false; + _soundIsOn = &_soundPlaying; + + _soundOn = true; + _musicOn = true; + _speechOn = true; } /** @@ -44,79 +47,90 @@ void Sound::syncSoundSettings() { _digitized = !ConfMan.getBool("mute"); _music = !ConfMan.getBool("mute") && !ConfMan.getBool("music_mute"); _voices = !ConfMan.getBool("mute") && !ConfMan.getBool("speech_mute") ? 1 : 0; - - // TODO: For now, keep sound completely mute until sound is implemented - _digitized = false; - _music = false; - _voices = 0; } void Sound::loadSound(const Common::String &name, int priority) { // TODO + warning("TODO: Sound::loadSound"); } bool Sound::playSound(const Common::String &name, WaitType waitType) { // TODO + warning("TODO: Sound::playSound"); return true; } void Sound::cacheSound(const Common::String &name, int index) { // TODO + warning("TODO: Sound::cacheSound"); } void Sound::playLoadedSound(int bufNum, int waitMode) { // TODO + warning("TODO: Sound::playLoadedSound"); } void Sound::playCachedSound(int index) { // TODO + warning("TODO: Sound::playCachedSound"); } void Sound::freeLoadedSounds() { // TODO + warning("TODO: Sound::clearLoadedSound"); } void Sound::clearCache() { // TODO + warning("TODO: Sound::clearCache"); } void Sound::stopSound() { // TODO + warning("TODO: Sound::stopSound"); } void Sound::playMusic(const Common::String &name) { // TODO + warning("TODO: Sound::playMusic"); } void Sound::stopMusic() { // TODO + warning("TODO: Sound::stopMusic"); } int Sound::loadSong(int songNumber) { // TODO + warning("TODO: Sound::loadSong"); return 0; } void Sound::startSong() { // TODO + warning("TODO: Sound::startSong"); } void Sound::freeSong() { // TODO + warning("TODO: Sound::freeSong"); } void Sound::stopSndFuncPtr(int v1, int v2) { // TODO + warning("TODO: Sound::stopSndFuncPtr"); } void Sound::waitTimerRoland(uint time) { // TODO + warning("TODO: Sound::waitTimerRoland"); } void Sound::freeDigiSound() { delete[] _digiBuf; _digiBuf = nullptr; _diskSoundPlaying = false; + _soundPlaying = false; } } // End of namespace Sherlock diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index 3bd3a99f07..1fd4c29b12 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -46,7 +46,8 @@ public: bool _speechOn; bool _playingEpilogue; bool _diskSoundPlaying; - byte *_soundIsOn; + bool _soundPlaying; + bool *_soundIsOn; byte *_digiBuf; public: Sound(SherlockEngine *vm); -- cgit v1.2.3 From d8673cfe44126f1d24ec0cff82a3407e9f891d7b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 6 May 2015 20:46:03 -0400 Subject: SHERLOCK: Dropped _saveSeqNum in favor of _savedSequences size --- engines/sherlock/talk.cpp | 3 +-- engines/sherlock/talk.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 11385ca978..b1f4d4e546 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -94,7 +94,6 @@ void TalkSequences::clear() { Talk::Talk(SherlockEngine *vm): _vm(vm) { _talkCounter = 0; _talkToAbort = false; - _saveSeqNum = 0; _speaker = 0; _talkIndex = 0; _talkTo = 0; @@ -1008,7 +1007,7 @@ void Talk::doScript(const Common::String &script) { int obj; int seqCount; - _saveSeqNum = 0; + _savedSequences.clear(); const byte *scriptStart = (const byte *)script.c_str(); const byte *str = scriptStart; diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index f96c3176d2..b44bccaab6 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -129,7 +129,6 @@ private: Common::Array TALK_SEQUENCES; private: SherlockEngine *_vm; - int _saveSeqNum; Common::Stack _savedSequences; Common::Stack _sequenceStack; Common::Stack _scriptStack; -- cgit v1.2.3 From 6c41a9be524385f16c33041885a7f5c4603a0f0e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 6 May 2015 23:34:57 -0400 Subject: SHERLOCK: Fix looking at Paul's Cap immediately after entering a scene --- engines/sherlock/people.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 5c4014f1a2..8f7b957db6 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -240,6 +240,9 @@ void People::reset() { p._noShapeSize = Common::Point(0, 0); p._goto = Common::Point(0, 0); p._status = 0; + + // Reset any walk path in progress when Sherlock leaves scenes + _walkTo.clear(); } /** -- cgit v1.2.3 From 97bec43799aa85b9ef49e4e26016de95dd054e71 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 6 May 2015 23:39:23 -0400 Subject: SHERLOCK: Minor comment updates --- engines/sherlock/people.cpp | 2 ++ engines/sherlock/sherlock.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 8f7b957db6..9c264b4754 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -221,6 +221,8 @@ People::~People() { * Reset the player data */ void People::reset() { + // Note: The engine has theoretical support for two player charactersm but only the first one is used. + // Watson is, instead, handled by a different sprite in each scene, with a very simple initial movement, if any Sprite &p = _data[PLAYER]; p._description = "Sherlock Holmes!"; diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 8b25615792..5a73b4fd1d 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -128,7 +128,7 @@ Common::Error SherlockEngine::run() { // Reset UI flags _ui->reset(); - // Reset the active characters to initially just Sherlock + // Reset the data for the player character (Sherlock) _people->reset(); // Initialize and load the scene. -- cgit v1.2.3 From 4884762e0471e358bc6416d8baf97e0685b1aa3c Mon Sep 17 00:00:00 2001 From: Strangerke Date: Thu, 7 May 2015 18:21:25 +0200 Subject: SHERLOCK: Reduce the scope of some variables --- engines/sherlock/animation.cpp | 3 +-- engines/sherlock/journal.cpp | 17 +++++++---------- engines/sherlock/map.cpp | 5 +++-- engines/sherlock/objects.cpp | 5 ++--- engines/sherlock/people.cpp | 2 +- 5 files changed, 14 insertions(+), 18 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index b1ec6590b1..62e6e4bebf 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -109,12 +109,11 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade, } int frameNumber = 0; - int imageFrame; Common::Point pt; bool skipped = false; while (!_vm->shouldQuit()) { // Get the next sprite to display - imageFrame = stream->readSint16LE(); + int imageFrame = stream->readSint16LE(); if (imageFrame == -2) { // End of animation reached diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 25b0bb5451..dfff6e9bb7 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -96,7 +96,6 @@ void Journal::record(int converseNum, int statementNum, bool replyOnly) { */ void Journal::loadJournalLocations() { Resources &res = *_vm->_res; - char c; _directory.clear(); @@ -123,6 +122,7 @@ void Journal::loadJournalLocations() { _locations.clear(); while (loc->pos() < loc->size()) { Common::String line; + char c; while ((c = loc->readByte()) != 0) line += c; @@ -564,9 +564,7 @@ bool Journal::doJournal(int direction, int howFar) { int lineNum = 0; int maxLines; int savedIndex; - int savedSub; int temp; - bool inc; const char *matchP; int width; @@ -663,7 +661,7 @@ bool Journal::doJournal(int direction, int howFar) { lineNum = 0; savedIndex = _index; - savedSub = _sub; + int savedSub = _sub; // Move a single page ahead do { @@ -725,7 +723,7 @@ bool Journal::doJournal(int direction, int howFar) { lineNum = 0; do { - inc = true; + bool inc = true; // If there wasn't any line to print at the top of the page, we won't need to // increment the y position @@ -955,9 +953,9 @@ bool Journal::handleEvents(int key) { screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), COMMAND_FOREGROUND, true, "Search"); bool notFound = false; - int dir; do { + int dir; if ((dir = getFindName(notFound)) != 0) { int savedIndex = _index; int savedSub = _sub; @@ -1016,6 +1014,8 @@ bool Journal::handleEvents(int key) { * Show the search submenu */ int Journal::getFindName(bool printError) { + enum Button { BTN_NONE, BTN_EXIT, BTN_BACKWARD, BTN_FORWARD }; + Events &events = *_vm->_events; Screen &screen = *_vm->_screen; Talk &talk = *_vm->_talk; @@ -1023,8 +1023,6 @@ int Journal::getFindName(bool printError) { int yp = 174; bool flag = false; Common::String name; - enum Button { BTN_NONE, BTN_EXIT, BTN_BACKWARD, BTN_FORWARD }; - Button found = BTN_NONE; int done = 0; byte color; @@ -1062,7 +1060,6 @@ int Journal::getFindName(bool printError) { for (int idx = 0; idx < 40 && !_vm->shouldQuit() && !events.kbHit() && !events._released; ++idx) { events.pollEvents(); events.setButtonState(); - events.wait(2); } @@ -1082,7 +1079,7 @@ int Journal::getFindName(bool printError) { do { events._released = false; - found = BTN_NONE; + Button found = BTN_NONE; while (!_vm->shouldQuit() && !events.kbHit() && !events._released) { found = BTN_NONE; diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index f572e3771a..4f04312ba7 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -95,10 +95,10 @@ void Map::loadSequences(int count, const byte *seq) { void Map::loadData() { // Load the list of location names Common::SeekableReadStream *txtStream = _vm->_res->load("chess.txt"); - char c; while (txtStream->pos() < txtStream->size()) { Common::String line; + char c; while ((c = txtStream->readByte()) != '\0') line += c; @@ -442,7 +442,6 @@ void Map::updateMap(bool flushScreen) { */ void Map::walkTheStreets() { People &people = *_vm->_people; - bool reversePath = false; Common::Array tempPath; // Get indexes into the path lists for the start and destination scenes @@ -463,6 +462,8 @@ void Map::walkTheStreets() { if (_charPoint == 51 || _oldCharPoint == 51) { people.setWalking(); } else { + bool reversePath = false; + // Check for moving the path backwards or forwards if (path[0] == 255) { reversePath = true; diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 6f4795de7e..f22bedfc44 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -835,15 +835,13 @@ int Object::checkNameForCodes(const Common::String &name, const char *const mess Talk &talk = *_vm->_talk; UserInterface &ui = *_vm->_ui; bool printed = false; - char ch; - const char *p; scene.toggleObject(name); if (name.hasPrefix("*")) { // A code was found printed = true; - ch = (name == "*") ? 0 : toupper(name[1]); + char ch = (name == "*") ? 0 : toupper(name[1]); switch (ch) { case 'C': @@ -880,6 +878,7 @@ int Object::checkNameForCodes(const Common::String &name, const char *const mess map._overPos.y = map[scene._goToScene].y * 100 + 900; } + const char *p; if ((p = strchr(name.c_str(), ',')) != nullptr) { ++p; diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 9c264b4754..84194059e1 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -287,7 +287,6 @@ void People::setWalking() { Scene &scene = *_vm->_scene; int oldDirection, oldFrame; Common::Point speed, delta; - int temp; // Flag that player has now walked in the scene scene._walkedInScene = true; @@ -311,6 +310,7 @@ void People::setWalking() { // Since we want the player to be centered on the destination they // clicked, but characters draw positions start at their left, move // the destination half the character width to draw him centered + int temp; if (_walkDest.x >= (temp = _player._imageFrame->_frame.w / 2)) _walkDest.x -= temp; -- cgit v1.2.3 From f6b6b4c7289d128d5784d809baf1b20ba42aae03 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Thu, 7 May 2015 18:24:50 +0200 Subject: SHERLOCK: Fix the way the sprite frames are freed --- engines/sherlock/resources.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index 788cacf82a..0be5bc814d 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -328,7 +328,7 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette, bool byte *data = new byte[frame._size]; stream.read(data, frame._size); decompressFrame(frame, data); - delete data; + delete[] data; push_back(frame); } -- cgit v1.2.3 From a0661c8d5a970791a6fac3e304fe975e8e61b5f9 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Thu, 7 May 2015 19:21:55 +0200 Subject: SHERLOCK: Reduce some more variable scopes --- engines/sherlock/objects.cpp | 2 +- engines/sherlock/scalpel/darts.cpp | 5 ++--- engines/sherlock/settings.cpp | 3 +-- engines/sherlock/user_interface.cpp | 25 ++++++++++--------------- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index f22bedfc44..8a7ae49e34 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -989,7 +989,6 @@ int Object::pickUpObject(const char *const messages[]) { UserInterface &ui = *_vm->_ui; int pickup = _pickup & 0x7f; bool printed = false; - bool takeFlag = true; int numObjects = 0; if (pickup == 99) { @@ -1014,6 +1013,7 @@ int Object::pickUpObject(const char *const messages[]) { ui._menuCounter = 30; } else { // Pick it up + bool takeFlag = true; if ((_pickup & 0x80) == 0) { // Play an animation if (pickup > 80) { diff --git a/engines/sherlock/scalpel/darts.cpp b/engines/sherlock/scalpel/darts.cpp index 476a3071c5..4b48a1dacf 100644 --- a/engines/sherlock/scalpel/darts.cpp +++ b/engines/sherlock/scalpel/darts.cpp @@ -69,7 +69,6 @@ Darts::Darts(ScalpelEngine *vm) : _vm(vm) { void Darts::playDarts() { Events &events = *_vm->_events; Screen &screen = *_vm->_screen; - int score, roundStartScore; int playerNumber = 0; int lastDart; @@ -82,6 +81,7 @@ void Darts::playDarts() { bool done = false; do { + int score, roundStartScore; roundStartScore = score = playerNumber == 0 ? _dartScore1 : _dartScore2; // Show player details @@ -502,7 +502,6 @@ int Darts::dartScore(const Common::Point &pt) { */ Common::Point Darts::getComputerDartDest(int playerNum) { Common::Point target; - int aim; int score = playerNum == 0 ? _dartScore1 : _dartScore2; if (score > 50) { @@ -515,7 +514,7 @@ Common::Point Darts::getComputerDartDest(int playerNum) { target.y += _vm->getRandomNumber(21) - 10; } } else { - aim = score; + int aim = score; bool done; Common::Point pt; diff --git a/engines/sherlock/settings.cpp b/engines/sherlock/settings.cpp index 1673eca389..e19aefd9c5 100644 --- a/engines/sherlock/settings.cpp +++ b/engines/sherlock/settings.cpp @@ -224,7 +224,6 @@ void Settings::show(SherlockEngine *vm) { Sound &sound = *vm->_sound; Talk &talk = *vm->_talk; UserInterface &ui = *vm->_ui; - int found; bool updateConfig = false; Settings settings(vm); @@ -234,7 +233,7 @@ void Settings::show(SherlockEngine *vm) { if (ui._menuCounter) ui.whileMenuCounter(); - found = -1; + int found = -1; ui._key = -1; scene.doBgAnim(); diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index d40e1cced1..a134b95196 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -531,13 +531,12 @@ void UserInterface::examine() { Scene &scene = *_vm->_scene; Talk &talk = *_vm->_talk; Common::Point pt = events.mousePos(); - int canimSpeed; if (pt.y < (CONTROLS_Y + 9)) { Object &obj = scene._bgShapes[_bgFound]; if (obj._lookcAnim != 0) { - canimSpeed = ((obj._lookcAnim & 0xe0) >> 5) + 1; + int canimSpeed = ((obj._lookcAnim & 0xe0) >> 5) + 1; scene._cAnimFramePause = obj._lookFrames; _cAnimStr = obj._examine; _cNum = (obj._lookcAnim & 0x1f) - 1; @@ -587,7 +586,6 @@ void UserInterface::lookScreen(const Common::Point &pt) { Common::Point mousePos = events.mousePos(); int temp; Common::String tempStr; - int x, width; // Don't display anything for right button command if ((events._rightPressed || events._rightPressed) && !events._pressed) @@ -612,7 +610,7 @@ void UserInterface::lookScreen(const Common::Point &pt) { if ((_menuMode == INV_MODE || _menuMode == USE_MODE || _menuMode == GIVE_MODE) && (inv._invMode == 2 || inv._invMode == 3)) { int width1 = 0, width2 = 0; - + int x, width; if (inv._invMode == 2) { // Using an object x = width = screen.stringWidth("Use "); @@ -743,9 +741,9 @@ void UserInterface::doEnvControl() { events.clearKeyboard(); // Check for a filename entry being highlighted - int found1 = 0; if ((events._pressed || events._released) && mousePos.y > (CONTROLS_Y + 10)) { + int found1 = 0; for (_selector = 0; (_selector < 5) && !found1; ++_selector) if (mousePos.y > (CONTROLS_Y + 11 + _selector * 10) && mousePos.y < (CONTROLS_Y + 21 + _selector * 10)) found1 = 1; @@ -1540,7 +1538,6 @@ void UserInterface::doTalkControl() { Sound &sound = *_vm->_sound; Talk &talk = *_vm->_talk; Common::Point mousePos = events.mousePos(); - int select; _key = _oldKey = -1; _keyboardInput = false; @@ -1728,7 +1725,7 @@ void UserInterface::doTalkControl() { talk.loadTalkFile(linkFilename); // Find the first new statement - select = _selector = _oldSelector = -1; + int select = _selector = _oldSelector = -1; for (uint idx = 0; idx < talk._statements.size() && select == -1; ++idx) { if (!talk._statements[idx]._talkMap) select = talk._talkIndex = idx; @@ -1795,7 +1792,6 @@ void UserInterface::journalControl() { Journal &journal = *_vm->_journal; Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; - int found; bool doneFlag = false; // Draw the journal screen @@ -1803,7 +1799,7 @@ void UserInterface::journalControl() { // Handle journal events do { - found = _key = -1; + _key = -1; events.setButtonState(); // Handle keypresses @@ -1846,12 +1842,11 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { Inventory &inv = *_vm->_inventory; Screen &screen = *_vm->_screen; Talk &talk = *_vm->_talk; - int savedSelector; if (str.hasPrefix("_")) { _lookScriptFlag = true; events.setCursor(MAGNIFY); - savedSelector = _selector; + int savedSelector = _selector; talk.talkTo(str.c_str() + 1); _lookScriptFlag = false; @@ -2255,11 +2250,7 @@ void UserInterface::checkAction(ActionType &action, const char *const messages[] Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; Talk &talk = *_vm->_talk; - bool printed = false; - bool doCAnim = true; - int cAnimNum; Common::Point pt(-1, -1); - int dir = -1; if (objNum >= 1000) // Ignore actions done on characters @@ -2277,12 +2268,14 @@ void UserInterface::checkAction(ActionType &action, const char *const messages[] } else { Object &obj = scene._bgShapes[objNum]; + int cAnimNum; if (action._cAnimNum == 0) // Really a 10 cAnimNum = 9; else cAnimNum = action._cAnimNum - 1; + int dir = -1; if (action._cAnimNum != 99) { CAnim &anim = scene._cAnim[cAnimNum]; @@ -2303,6 +2296,7 @@ void UserInterface::checkAction(ActionType &action, const char *const messages[] // Has a value, so do action // Show wait cursor whilst walking to object and doing action events.setCursor(WAIT); + bool printed = false; for (int nameIdx = 0; nameIdx < 4; ++nameIdx) { if (action._names[nameIdx].hasPrefix("*") && action._names[nameIdx].size() >= 2 @@ -2314,6 +2308,7 @@ void UserInterface::checkAction(ActionType &action, const char *const messages[] } } + bool doCAnim = true; for (int nameIdx = 0; nameIdx < 4; ++nameIdx) { if (action._names[nameIdx].hasPrefix("*") && action._names[nameIdx].size() >= 2) { char ch = toupper(action._names[nameIdx][1]); -- cgit v1.2.3 From d9e93f8e015ce27a95090e854494c4b3f7d1c0d4 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Thu, 7 May 2015 19:33:44 +0200 Subject: SHERLOCK: some code formatting --- engines/sherlock/animation.cpp | 22 +++--- engines/sherlock/decompress.cpp | 78 ++++++++++----------- engines/sherlock/detection.cpp | 4 +- engines/sherlock/events.cpp | 4 +- engines/sherlock/graphics.cpp | 8 +-- engines/sherlock/inventory.cpp | 52 +++++++------- engines/sherlock/journal.cpp | 32 ++++----- engines/sherlock/map.cpp | 8 +-- engines/sherlock/objects.cpp | 28 ++++---- engines/sherlock/objects.h | 4 +- engines/sherlock/people.cpp | 10 +-- engines/sherlock/people.h | 16 ++--- engines/sherlock/resources.cpp | 12 ++-- engines/sherlock/resources.h | 2 +- engines/sherlock/saveload.cpp | 18 ++--- engines/sherlock/scalpel/darts.cpp | 18 ++--- engines/sherlock/scalpel/scalpel.cpp | 38 +++++----- engines/sherlock/scene.cpp | 34 ++++----- engines/sherlock/screen.cpp | 16 ++--- engines/sherlock/settings.cpp | 46 ++++++------- engines/sherlock/sherlock.cpp | 4 +- engines/sherlock/sound.h | 2 +- engines/sherlock/talk.cpp | 50 +++++++------- engines/sherlock/user_interface.cpp | 130 +++++++++++++++++------------------ 24 files changed, 318 insertions(+), 318 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 62e6e4bebf..fc84680d5e 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -26,30 +26,30 @@ namespace Sherlock { -// The following are a list of filenames played in the prologue that have +// The following are a list of filenames played in the prologue that have // special effects associated with them at specific frames #define FRAMES_END 32000 #define PROLOGUE_NAMES_COUNT 6 #define TITLE_NAMES_COUNT 7 -static const char *const PROLOGUE_NAMES[6] = { - "subway1", "subway2", "finale2", "suicid", "coff3", "coff4" +static const char *const PROLOGUE_NAMES[6] = { + "subway1", "subway2", "finale2", "suicid", "coff3", "coff4" }; -static const int PROLOGUE_FRAMES[6][9] = { +static const int PROLOGUE_FRAMES[6][9] = { { 4, 26, 54, 72, 92, 134, FRAMES_END }, { 2, 80, 95, 117, 166, FRAMES_END }, { 1, FRAMES_END }, { 42, FRAMES_END }, { FRAMES_END }, - { FRAMES_END } + { FRAMES_END } }; // Title animations file list -static const char *const TITLE_NAMES[7] = { - "27pro1", "14note", "coff1", "coff2", "coff3", "coff4", "14kick" +static const char *const TITLE_NAMES[7] = { + "27pro1", "14note", "coff1", "coff2", "coff3", "coff4", "14kick" }; -static const int TITLE_FRAMES[7][9] = { +static const int TITLE_FRAMES[7][9] = { { 29, 131, FRAMES_END }, { 55, 80, 95, 117, 166, FRAMES_END }, { 15, FRAMES_END }, @@ -67,7 +67,7 @@ Animation::Animation(SherlockEngine *vm): _vm(vm) { /** * Play a full-screen animation */ -bool Animation::play(const Common::String &filename, int minDelay, int fade, +bool Animation::play(const Common::String &filename, int minDelay, int fade, bool setPalette, int speed) { Events &events = *_vm->_events; Screen &screen = *_vm->_screen; @@ -98,7 +98,7 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade, // Load initial image Common::String vdaName = baseName + ".vda"; ImageFile images(vdaName, true, true); - + events.wait(minDelay); if (fade != 0 && fade != 255) screen.fadeToBlack(); @@ -166,7 +166,7 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade, break; } } - + events.clearEvents(); sound.stopSound(); delete stream; diff --git a/engines/sherlock/decompress.cpp b/engines/sherlock/decompress.cpp index 61110be840..b319bc90c8 100644 --- a/engines/sherlock/decompress.cpp +++ b/engines/sherlock/decompress.cpp @@ -36,47 +36,47 @@ Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source, int outSize = source.readSint32LE(); } - byte lzWindow[4096]; - uint16 lzWindowPos; - uint16 cmd; - - byte *outBuffer = new byte[outSize]; - byte *outBufferEnd = outBuffer + outSize; - Common::MemoryReadStream *outS = new Common::MemoryReadStream(outBuffer, outSize, DisposeAfterUse::YES); - - memset(lzWindow, 0xFF, 0xFEE); - lzWindowPos = 0xFEE; - cmd = 0; + byte lzWindow[4096]; + uint16 lzWindowPos; + uint16 cmd; - while (1) { - cmd >>= 1; - if (!(cmd & 0x100)) { - cmd = source.readByte() | 0xFF00; - } - if (cmd & 1) { - byte literal = source.readByte(); - *outBuffer++ = literal; - lzWindow[lzWindowPos] = literal; - lzWindowPos = (lzWindowPos + 1) & 0x0FFF; - } else { - int copyPos, copyLen; - copyPos = source.readByte(); - copyLen = source.readByte(); - copyPos = copyPos | ((copyLen & 0xF0) << 4); - copyLen = (copyLen & 0x0F) + 3; - while (copyLen--) { - byte literal = lzWindow[copyPos]; - copyPos = (copyPos + 1) & 0x0FFF; - *outBuffer++ = literal; - lzWindow[lzWindowPos] = literal; - lzWindowPos = (lzWindowPos + 1) & 0x0FFF; - } - } - if (outBuffer >= outBufferEnd) - break; - } + byte *outBuffer = new byte[outSize]; + byte *outBufferEnd = outBuffer + outSize; + Common::MemoryReadStream *outS = new Common::MemoryReadStream(outBuffer, outSize, DisposeAfterUse::YES); - return outS; + memset(lzWindow, 0xFF, 0xFEE); + lzWindowPos = 0xFEE; + cmd = 0; + + while (1) { + cmd >>= 1; + if (!(cmd & 0x100)) + cmd = source.readByte() | 0xFF00; + + if (cmd & 1) { + byte literal = source.readByte(); + *outBuffer++ = literal; + lzWindow[lzWindowPos] = literal; + lzWindowPos = (lzWindowPos + 1) & 0x0FFF; + } else { + int copyPos, copyLen; + copyPos = source.readByte(); + copyLen = source.readByte(); + copyPos = copyPos | ((copyLen & 0xF0) << 4); + copyLen = (copyLen & 0x0F) + 3; + while (copyLen--) { + byte literal = lzWindow[copyPos]; + copyPos = (copyPos + 1) & 0x0FFF; + *outBuffer++ = literal; + lzWindow[lzWindowPos] = literal; + lzWindowPos = (lzWindowPos + 1) & 0x0FFF; + } + } + if (outBuffer >= outBufferEnd) + break; + } + + return outS; } } // namespace Sherlock diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp index 14fc04cc73..734db007ba 100644 --- a/engines/sherlock/detection.cpp +++ b/engines/sherlock/detection.cpp @@ -148,13 +148,13 @@ int SherlockMetaEngine::getMaximumSaveSlot() const { /** * Deletes a savegame in the specified slot */ -void SherlockMetaEngine::removeSaveState(const char *target, int slot) const { +void SherlockMetaEngine::removeSaveState(const char *target, int slot) const { Common::String filename = Sherlock::SaveManager(nullptr, target).generateSaveName(slot); g_system->getSavefileManager()->removeSavefile(filename); } /** - * Given a specified savegame slot, returns extended information for the save + * Given a specified savegame slot, returns extended information for the save */ SaveStateDescriptor SherlockMetaEngine::querySaveMetaInfos(const char *target, int slot) const { Common::String filename = Sherlock::SaveManager(nullptr, target).generateSaveName(slot); diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index a4fc93edd9..4e3f81e588 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -95,7 +95,7 @@ void Events::hideCursor() { } /** - * Returns the cursor + * Returns the cursor */ CursorId Events::getCursor() const { return _cursorId; @@ -200,7 +200,7 @@ bool Events::checkForNextFrameCounter() { /** * Get a pending keypress */ -Common::KeyState Events::getKey() { +Common::KeyState Events::getKey() { Common::KeyState keyState = _pendingKeys.pop(); if ((keyState.flags & Common::KBD_SHIFT) != 0) keyState.ascii = toupper(keyState.ascii); diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index 2095e7d35d..132d3fa089 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -72,7 +72,7 @@ void Surface::blitFrom(const Graphics::Surface &src) { void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt) { Common::Rect drawRect(0, 0, src.w, src.h); Common::Point destPt = pt; - + if (destPt.x < 0) { drawRect.left += -destPt.x; destPt.x = 0; @@ -125,7 +125,7 @@ void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &p bool flipped, int overrideColor) { Common::Rect drawRect(0, 0, src.w, src.h); Common::Rect destRect(pt.x, pt.y, pt.x + src.w, pt.y + src.h); - + // Clip the display area to on-screen if (!clip(drawRect, destRect)) // It's completely off-screen @@ -166,7 +166,7 @@ void Surface::fillRect(int x1, int y1, int x2, int y2, byte color) { * Fill a given area of the surface with a given color */ void Surface::fillRect(const Common::Rect &r, byte color) { - Graphics::Surface::fillRect(r, color); + Graphics::Surface::fillRect(r, color); addDirtyRect(r); } @@ -198,7 +198,7 @@ bool Surface::clip(Common::Rect &srcBounds, Common::Rect &destBounds) { srcBounds.left += -destBounds.left; destBounds.left = 0; } - + return true; } diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index 935a306619..99db461ea4 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -26,8 +26,8 @@ namespace Sherlock { InventoryItem::InventoryItem(int requiredFlag, const Common::String &name, - const Common::String &description, const Common::String &examine) : - _requiredFlag(requiredFlag), _name(name), _description(description), + const Common::String &description, const Common::String &examine) : + _requiredFlag(requiredFlag), _name(name), _description(description), _examine(examine), _lookFlag(0) { } @@ -74,7 +74,7 @@ void Inventory::freeInv() { void Inventory::freeGraphics() { for (uint idx = 0; idx < MAX_VISIBLE_INVENTORY; ++idx) delete _invShapes[idx]; - + Common::fill(&_invShapes[0], &_invShapes[MAX_VISIBLE_INVENTORY], (ImageFile *)nullptr); _invGraphicsLoaded = false; } @@ -98,7 +98,7 @@ void Inventory::loadInv() { _names.push_back(name); } - + delete stream; loadGraphics(); @@ -181,7 +181,7 @@ void Inventory::putInv(int slamIt) { // Draw the item image Graphics::Surface &img = (*_invShapes[itemNum])[0]._frame; - bb.transBlitFrom(img, Common::Point(6 + itemNum * 52 + ((47 - img.w) / 2), + bb.transBlitFrom(img, Common::Point(6 + itemNum * 52 + ((47 - img.w) / 2), 163 + ((33 - img.h) / 2))); } @@ -206,7 +206,7 @@ void Inventory::putInv(int slamIt) { * 0 = plain inventory mode * 2 = use inventory mode * 3 = give inventory mode - * 128 = Draw window in the back buffer, but don't display it + * 128 = Draw window in the back buffer, but don't display it */ void Inventory::drawInventory(int flag) { Screen &screen = *_vm->_screen; @@ -224,7 +224,7 @@ void Inventory::drawInventory(int flag) { Surface &bb = *screen._backBuffer; bb.fillRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y1 + 10), BORDER_COLOR); bb.fillRect(Common::Rect(0, CONTROLS_Y1 + 10, 2, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); - bb.fillRect(Common::Rect(SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y1 + 10, + bb.fillRect(Common::Rect(SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y1 + 10, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); bb.fillRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - 2, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); @@ -232,21 +232,21 @@ void Inventory::drawInventory(int flag) { INV_BACKGROUND); // Draw the buttons - screen.makeButton(Common::Rect(INVENTORY_POINTS[0][0], CONTROLS_Y1, INVENTORY_POINTS[0][1], + screen.makeButton(Common::Rect(INVENTORY_POINTS[0][0], CONTROLS_Y1, INVENTORY_POINTS[0][1], CONTROLS_Y1 + 10), INVENTORY_POINTS[0][2] - screen.stringWidth("Exit") / 2, "Exit"); screen.makeButton(Common::Rect(INVENTORY_POINTS[1][0], CONTROLS_Y1, INVENTORY_POINTS[1][1], CONTROLS_Y1 + 10), INVENTORY_POINTS[1][2] - screen.stringWidth("Look") / 2, "Look"); - screen.makeButton(Common::Rect(INVENTORY_POINTS[2][0], CONTROLS_Y1, INVENTORY_POINTS[2][1], + screen.makeButton(Common::Rect(INVENTORY_POINTS[2][0], CONTROLS_Y1, INVENTORY_POINTS[2][1], CONTROLS_Y1 + 10), INVENTORY_POINTS[2][2] - screen.stringWidth("Use") / 2, "Use"); - screen.makeButton(Common::Rect(INVENTORY_POINTS[3][0], CONTROLS_Y1, INVENTORY_POINTS[3][1], + screen.makeButton(Common::Rect(INVENTORY_POINTS[3][0], CONTROLS_Y1, INVENTORY_POINTS[3][1], CONTROLS_Y1 + 10), INVENTORY_POINTS[3][2] - screen.stringWidth("Give") / 2, "Give"); - screen.makeButton(Common::Rect(INVENTORY_POINTS[4][0], CONTROLS_Y1, INVENTORY_POINTS[4][1], + screen.makeButton(Common::Rect(INVENTORY_POINTS[4][0], CONTROLS_Y1, INVENTORY_POINTS[4][1], CONTROLS_Y1 + 10), INVENTORY_POINTS[4][2], "^^"); - screen.makeButton(Common::Rect(INVENTORY_POINTS[5][0], CONTROLS_Y1, INVENTORY_POINTS[5][1], + screen.makeButton(Common::Rect(INVENTORY_POINTS[5][0], CONTROLS_Y1, INVENTORY_POINTS[5][1], CONTROLS_Y1 + 10), INVENTORY_POINTS[5][2], "^"); - screen.makeButton(Common::Rect(INVENTORY_POINTS[6][0], CONTROLS_Y1, INVENTORY_POINTS[6][1], + screen.makeButton(Common::Rect(INVENTORY_POINTS[6][0], CONTROLS_Y1, INVENTORY_POINTS[6][1], CONTROLS_Y1 + 10), INVENTORY_POINTS[6][2], "_"); - screen.makeButton(Common::Rect(INVENTORY_POINTS[7][0], CONTROLS_Y1, INVENTORY_POINTS[7][1], + screen.makeButton(Common::Rect(INVENTORY_POINTS[7][0], CONTROLS_Y1, INVENTORY_POINTS[7][1], CONTROLS_Y1 + 10), INVENTORY_POINTS[7][2], "__"); if (tempFlag == 128) @@ -289,43 +289,43 @@ void Inventory::invCommands(bool slamIt) { UserInterface &ui = *_vm->_ui; if (slamIt) { - screen.buttonPrint(Common::Point(INVENTORY_POINTS[0][2], CONTROLS_Y1), + screen.buttonPrint(Common::Point(INVENTORY_POINTS[0][2], CONTROLS_Y1), _invMode == 0 ? COMMAND_HIGHLIGHTED :COMMAND_FOREGROUND, true, "Exit"); - screen.buttonPrint(Common::Point(INVENTORY_POINTS[1][2], CONTROLS_Y1), + screen.buttonPrint(Common::Point(INVENTORY_POINTS[1][2], CONTROLS_Y1), _invMode == 1 ? COMMAND_HIGHLIGHTED :COMMAND_FOREGROUND, true, "Look"); - screen.buttonPrint(Common::Point(INVENTORY_POINTS[2][2], CONTROLS_Y1), + screen.buttonPrint(Common::Point(INVENTORY_POINTS[2][2], CONTROLS_Y1), _invMode == 2 ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, true, "Use"); - screen.buttonPrint(Common::Point(INVENTORY_POINTS[3][2], CONTROLS_Y1), + screen.buttonPrint(Common::Point(INVENTORY_POINTS[3][2], CONTROLS_Y1), _invMode == 3 ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, true, "Give"); - screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1), + screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1), _invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND, "^^"); - screen.print(Common::Point(INVENTORY_POINTS[5][2], CONTROLS_Y1 + 1), + screen.print(Common::Point(INVENTORY_POINTS[5][2], CONTROLS_Y1 + 1), _invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND, "^"); - screen.print(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1 + 1), + screen.print(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1 + 1), (_holdings - _invIndex <= 6) ? COMMAND_NULL : COMMAND_FOREGROUND, "_"); - screen.print(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1 + 1), + screen.print(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1 + 1), (_holdings - _invIndex <= 6) ? COMMAND_NULL : COMMAND_FOREGROUND, "__"); if (_invMode != 1) ui.clearInfo(); } else { - screen.buttonPrint(Common::Point(INVENTORY_POINTS[0][2], CONTROLS_Y1), + screen.buttonPrint(Common::Point(INVENTORY_POINTS[0][2], CONTROLS_Y1), _invMode == 0 ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, false, "Exit"); - screen.buttonPrint(Common::Point(INVENTORY_POINTS[1][2], CONTROLS_Y1), + screen.buttonPrint(Common::Point(INVENTORY_POINTS[1][2], CONTROLS_Y1), _invMode == 1 ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, false, "Look"); - screen.buttonPrint(Common::Point(INVENTORY_POINTS[2][2], CONTROLS_Y1), + screen.buttonPrint(Common::Point(INVENTORY_POINTS[2][2], CONTROLS_Y1), _invMode == 2 ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, false, "Use"); - screen.buttonPrint(Common::Point(INVENTORY_POINTS[3][2], CONTROLS_Y1), + screen.buttonPrint(Common::Point(INVENTORY_POINTS[3][2], CONTROLS_Y1), _invMode == 3 ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, false, "Give"); screen.gPrint(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1), diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index dfff6e9bb7..26aaa7a1a0 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -29,7 +29,7 @@ namespace Sherlock { #define LINES_PER_PAGE 11 // Positioning of buttons in the journal view -const int JOURNAL_POINTS[9][3] = { +const int JOURNAL_POINTS[9][3] = { { 6, 68, 37 }, { 69, 131, 100 }, { 132, 192, 162 }, @@ -38,7 +38,7 @@ const int JOURNAL_POINTS[9][3] = { { 6, 82, 44 }, { 83, 159, 121 }, { 160, 236, 198 }, - { 237, 313, 275 } + { 237, 313, 275 } }; const int SEARCH_POINTS[3][3] = { @@ -101,7 +101,7 @@ void Journal::loadJournalLocations() { Common::SeekableReadStream *dir = res.load("talk.lib"); dir->skip(4); // Skip header - + // Get the numer of entries _directory.resize(dir->readUint16LE()); @@ -198,8 +198,8 @@ int Journal::loadJournalFile(bool alreadyLoaded) { const char *lineP = journalString.c_str() + journalString.size() - 1; while (width > 230 || *lineP != ' ') width -= screen.charWidth(*lineP--); - - // Split the header into two lines, and add a '@' prefix + + // Split the header into two lines, and add a '@' prefix // to the second line as well journalString = Common::String(journalString.c_str(), lineP) + "\n@" + Common::String(lineP + 1); @@ -217,7 +217,7 @@ int Journal::loadJournalFile(bool alreadyLoaded) { journalString += "asked "; else journalString += "said to "; - + switch (talk._talkTo) { case 1: journalString += "me"; @@ -364,7 +364,7 @@ int Journal::loadJournalFile(bool alreadyLoaded) { case WALK_TO_COORDS: case MOVE_MOUSE: - replyP += 4; + replyP += 4; break; case SET_FLAG: @@ -422,13 +422,13 @@ int Journal::loadJournalFile(bool alreadyLoaded) { // past it, so the @ won't be included in the line width calculation if (*startP == '@') ++startP; - + // Build up chacters until a full line is found int width = 0; const char *endP = startP; while (width < 230 && *endP && *endP != '\n' && (endP - startP) < 79) width += screen.charWidth(*endP++); - + // If word wrapping, move back to end of prior word if (width >= 230 || (endP - startP) >= 79) { while (*--endP != ' ') @@ -520,7 +520,7 @@ void Journal::drawInterface() { } doArrows(); - + // Show the entire screen screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } @@ -650,7 +650,7 @@ bool Journal::doJournal(int direction, int howFar) { case 2: case 3: - // Move howFar lines ahead unless the end of the journal is reached, + // Move howFar lines ahead unless the end of the journal is reached, // or a searched for keyword is found for (temp = 0; (temp < (howFar / LINES_PER_PAGE)) && !endJournal && !searchSuccessful; ++temp) { // Handle animating mouse cursor @@ -687,7 +687,7 @@ bool Journal::doJournal(int direction, int howFar) { _sub = 0; maxLines = loadJournalFile(false); } - } while (!endJournal && !maxLines); + } while (!endJournal && !maxLines); } ++lineNum; @@ -919,7 +919,7 @@ bool Journal::handleEvents(int key) { doJournal(1, (_page - 1) * LINES_PER_PAGE); else doJournal(1, 10 * LINES_PER_PAGE); - + doArrows(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } @@ -952,7 +952,7 @@ bool Journal::handleEvents(int key) { if (((found == BTN_SEARCH && events._released) || key == 'S') && !_journal.empty()) { screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), COMMAND_FOREGROUND, true, "Search"); bool notFound = false; - + do { int dir; @@ -1076,7 +1076,7 @@ int Journal::getFindName(bool printError) { xp = 15 + screen.stringWidth(name); yp = 186; - + do { events._released = false; Button found = BTN_NONE; @@ -1141,7 +1141,7 @@ int Journal::getFindName(bool printError) { } if (keyState.keycode >= Common::KEYCODE_SPACE && keyState.keycode <= Common::KEYCODE_z - && keyState.keycode != Common::KEYCODE_AT && name.size() < 50 + && keyState.keycode != Common::KEYCODE_AT && name.size() < 50 && (xp + screen.charWidth(keyState.keycode)) < 296) { screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), BUTTON_MIDDLE); screen.print(Common::Point(xp, yp), TALK_FOREGROUND, "%c", (char)keyState.keycode); diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index 4f04312ba7..3879e904fa 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -180,7 +180,7 @@ int Map::show() { // Ignore scrolling attempts until the screen is drawn if (!_drawMap) { Common::Point pt = events.mousePos(); - + // Check for vertical map scrolling if ((pt.y > (SHERLOCK_SCREEN_HEIGHT - 10) && _bigPos.y < 200) || (pt.y < 10 && _bigPos.y > 0)) { if (pt.y > (SHERLOCK_SCREEN_HEIGHT - 10)) @@ -336,7 +336,7 @@ void Map::showPlaces() { if (pt.x >= _bigPos.x && (pt.x - _bigPos.x) < SHERLOCK_SCREEN_WIDTH && pt.y >= _bigPos.y && (pt.y - _bigPos.y) < SHERLOCK_SCREEN_HEIGHT) { if (_vm->readFlags(idx)) { - screen._backBuffer1.transBlitFrom((*_iconShapes)[pt._translate], + screen._backBuffer1.transBlitFrom((*_iconShapes)[pt._translate], Common::Point(pt.x - _bigPos.x - 6, pt.y - _bigPos.y - 12)); } } @@ -372,7 +372,7 @@ void Map::showPlaceName(int idx, bool highlighted) { if (!_cursorIndex) { saveIcon(people[AL]._imageFrame, _lDrawnPos); - + bool flipped = people[AL]._sequenceNumber == MAP_DOWNLEFT || people[AL]._sequenceNumber == MAP_LEFT || people[AL]._sequenceNumber == MAP_UPLEFT; screen._backBuffer1.transBlitFrom(people[AL]._imageFrame->_frame, _lDrawnPos, flipped); @@ -510,7 +510,7 @@ void Map::saveIcon(ImageFrame *src, const Common::Point &pt) { size.x += pos.x; pos.x = 0; } - + if (pos.y < 0) { size.y += pos.y; pos.y = 0; diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 8a7ae49e34..40c8b954cb 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -72,7 +72,7 @@ void Sprite::clear() { * Updates the image frame poiner for the sprite */ void Sprite::setImageFrame() { - int imageNumber = (*_sequences)[_sequenceNumber][_frameNumber] + + int imageNumber = (*_sequences)[_sequenceNumber][_frameNumber] + (*_sequences)[_sequenceNumber][0] - 2; _imageFrame = &(*_images)[imageNumber]; } @@ -171,7 +171,7 @@ void Sprite::adjustSprite() { if (people._hSavedFacing > 100 && people._hSavedPos.x < 1) people._hSavedPos.x = 100; } - } + } } } @@ -241,7 +241,7 @@ void Sprite::checkSprite() { if (obj._aType == PAL_CHANGE) // Invert percentage palPercent = 100 - palPercent; - + for (int idx = palStart; idx < (palStart + palLength); ++idx) screen._sMap[idx] = screen._cMap[idx] * palPercent / 100; @@ -320,7 +320,7 @@ void Sprite::checkSprite() { walkPos.x = objBounds.left - CLEAR_DIST_X; } - walkPos.y = (_delta.y >= 0) ? objBounds.top - CLEAR_DIST_Y : + walkPos.y = (_delta.y >= 0) ? objBounds.top - CLEAR_DIST_Y : objBounds.bottom + CLEAR_DIST_Y; } else { // Impact occurred due to horizontal movement @@ -362,11 +362,11 @@ void Sprite::checkSprite() { /*----------------------------------------------------------------*/ /** - * Synchronize the data for a savegame + * Synchronize the data for a savegame */ void ActionType::synchronize(Common::SeekableReadStream &s) { char buffer[12]; - + _cAnimNum = s.readByte(); _cAnimSpeed = s.readByte(); if (_cAnimSpeed & 0x80) @@ -388,7 +388,7 @@ UseType::UseType() { } /** - * Synchronize the data for a savegame + * Synchronize the data for a savegame */ void UseType::synchronize(Common::SeekableReadStream &s) { char buffer[12]; @@ -489,7 +489,7 @@ void Object::synchronize(Common::SeekableReadStream &s) { _oldSize.y = s.readUint16LE(); _goto.x = s.readSint16LE(); _goto.y = s.readSint16LE(); - + _pickup = s.readByte(); _defaultCommand = s.readByte(); _lookFlag = s.readUint16LE(); @@ -500,7 +500,7 @@ void Object::synchronize(Common::SeekableReadStream &s) { _status = s.readUint16LE(); _misc = s.readByte(); _maxFrames = s.readUint16LE(); - _flags = s.readByte(); + _flags = s.readByte(); _aOpen.synchronize(s); _aType = (AType)s.readByte(); _lookFrames = s.readByte(); @@ -518,7 +518,7 @@ void Object::synchronize(Common::SeekableReadStream &s) { s.skip(1); _aMove.synchronize(s); s.skip(8); - + for (int idx = 0; idx < 4; ++idx) _use[idx].synchronize(s); } @@ -861,8 +861,8 @@ int Object::checkNameForCodes(const Common::String &name, const char *const mess // A: Add onto existing co-ordinates Common::String sx(name.c_str() + 2, name.c_str() + 5); Common::String sy(name.c_str() + 6, name.c_str() + 9); - - if (ch == 'G') + + if (ch == 'G') _position = Common::Point(atoi(sx.c_str()), atoi(sy.c_str())); else _position += Common::Point(atoi(sx.c_str()), atoi(sy.c_str())); @@ -1055,7 +1055,7 @@ int Object::pickUpObject(const char *const messages[]) { if (!printed) { ui._infoFlag++; ui.clearInfo(); - + Common::String itemName = _description; itemName.setChar(tolower(itemName[0]), 0); screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "Picked up %s", itemName.c_str()); @@ -1096,7 +1096,7 @@ const Common::Rect Object::getOldBounds() const { /*----------------------------------------------------------------*/ /** - * Synchronize the data for a savegame + * Synchronize the data for a savegame */ void CAnim::synchronize(Common::SeekableReadStream &s) { char buffer[12]; diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 10b491e5d7..861858c58e 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -75,7 +75,7 @@ enum { #define MAX_FRAME 30 // code put into sequences to defines 1-10 type seqs -#define SEQ_TO_CODE 67 +#define SEQ_TO_CODE 67 #define FLIP_CODE (64 + 128) #define SOUND_CODE (34 + 128) @@ -216,7 +216,7 @@ public: int _seqTo; // Allows 1-5, 8-3 type sequences encoded in 2 bytes uint _descOffset; // Tells where description starts in DescText int _seqCounter2; // Counter of calling frame sequence - uint _seqSize; // Tells where description starts + uint _seqSize; // Tells where description starts ActionType _aMove; UseType _use[4]; diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 84194059e1..ee5f3bcb80 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -33,7 +33,7 @@ namespace Sherlock { // Characer animation sequences static const uint8 CHARACTER_SEQUENCES[MAX_HOLMES_SEQUENCE][MAX_FRAME] = { { 29, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Right - { 22, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Down + { 22, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Down { 29, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Left { 15, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Up { 42, 1, 2, 3, 4, 5, 0 }, // Goto Stand Right @@ -116,7 +116,7 @@ const char PORTRAITS[MAX_PEOPLE][5] = { { "NIGE" }, // Nigel Jameson { "JONA" }, // Jonas (newspaper seller) { "DUGA" }, // Constable Dugan - { "INSP" } // Inspector Lestrade (Scotland Yard) + { "INSP" } // Inspector Lestrade (Scotland Yard) }; const char *const NAMES[MAX_PEOPLE] = { @@ -421,7 +421,7 @@ void People::setWalking() { if (!_player._walkCount) gotoStand(_player); - // If the sequence is the same as when we started, then Holmes was + // If the sequence is the same as when we started, then Holmes was // standing still and we're trying to re-stand him, so reset Holmes' // rame to the old frame number from before it was reset to 0 if (_player._sequenceNumber == oldDirection) @@ -429,7 +429,7 @@ void People::setWalking() { } /** - * Bring a moving character to a standing position. If the Scalpel chessboard + * Bring a moving character to a standing position. If the Scalpel chessboard * is being displayed, then the chraracter will always face down. */ void People::gotoStand(Sprite &sprite) { @@ -516,7 +516,7 @@ void People::walkToCoords(const Common::Point &destPos, int destDir) { */ void People::goAllTheWay() { Scene &scene = *_vm->_scene; - Common::Point srcPt(_player._position.x / 100 + _player.frameWidth() / 2, + Common::Point srcPt(_player._position.x / 100 + _player.frameWidth() / 2, _player._position.y / 100); // Get the zone the player is currently in diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index f1ed3496a1..01ecd1a09a 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -32,11 +32,11 @@ namespace Sherlock { // People definitions enum PeopleId { - PLAYER = 0, - AL = 0, - PEG = 1, + PLAYER = 0, + AL = 0, + PEG = 1, NUM_OF_PEOPLE = 2, // Holmes and Watson - MAX_PEOPLE = 66 // Total of all NPCs + MAX_PEOPLE = 66 // Total of all NPCs }; // Animation sequence identifiers for characters @@ -92,13 +92,13 @@ public: People(SherlockEngine *vm); ~People(); - Person &operator[](PeopleId id) { + Person &operator[](PeopleId id) { assert(id < NUM_OF_PEOPLE); - return _data[id]; + return _data[id]; } - Person &operator[](int idx) { + Person &operator[](int idx) { assert(idx < NUM_OF_PEOPLE); - return _data[idx]; + return _data[idx]; } bool isHolmesActive() const { return _walkLoaded && _holmesOn; } diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index 0be5bc814d..715ca492ae 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -116,8 +116,8 @@ Resources::Resources() { * Adds the specified file to the cache. If it's a library file, takes care of * loading it's index for future use */ -void Resources::addToCache(const Common::String &filename) { - _cache.load(filename); +void Resources::addToCache(const Common::String &filename) { + _cache.load(filename); // Check to see if the file is a library Common::SeekableReadStream *stream = load(filename); @@ -270,10 +270,10 @@ void ImageFile::setVm(SherlockEngine *vm) { ImageFile::ImageFile(const Common::String &name, bool skipPal, bool animImages) { Common::SeekableReadStream *stream = _vm->_res->load(name); - + Common::fill(&_palette[0], &_palette[PALETTE_SIZE], 0); load(*stream, skipPal, animImages); - + delete stream; } @@ -327,7 +327,7 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette, bool // Load data for frame and decompress it byte *data = new byte[frame._size]; stream.read(data, frame._size); - decompressFrame(frame, data); + decompressFrame(frame, data); delete[] data; push_back(frame); @@ -344,7 +344,7 @@ void ImageFile::loadPalette(Common::SeekableReadStream &stream) { stream.skip(1); // Skip paletteBase byte bool rleEncoded = stream.readByte() == 1; int size = v1 * v2; - + if ((size - 12) == PALETTE_SIZE && !rleEncoded) { // Found palette, so read it in stream.seek(2 + 12, SEEK_CUR); diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h index b173884322..d53351e085 100644 --- a/engines/sherlock/resources.h +++ b/engines/sherlock/resources.h @@ -42,7 +42,7 @@ struct LibraryEntry { int _index; LibraryEntry() : _index(0), _offset(0), _size(0) {} - LibraryEntry(int index, uint32 offset, uint32 size) : + LibraryEntry(int index, uint32 offset, uint32 size) : _index(index), _offset(offset), _size(size) {} }; typedef Common::HashMap LibraryIndex; diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index 71e21618ae..61fe9f30bf 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -40,7 +40,7 @@ const int ENV_POINTS[6][3] = { /*----------------------------------------------------------------*/ -SaveManager::SaveManager(SherlockEngine *vm, const Common::String &target) : +SaveManager::SaveManager(SherlockEngine *vm, const Common::String &target) : _vm(vm), _target(target) { _saveThumb = nullptr; _envMode = SAVEMODE_NONE; @@ -71,7 +71,7 @@ void SaveManager::drawInterface() { screen._backBuffer1.fillRect(Common::Rect(0, 199, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); screen._backBuffer1.fillRect(Common::Rect(2, CONTROLS_Y + 10, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT - 2), INV_BACKGROUND); - screen.makeButton(Common::Rect(ENV_POINTS[0][0], CONTROLS_Y, ENV_POINTS[0][1], CONTROLS_Y + 10), + screen.makeButton(Common::Rect(ENV_POINTS[0][0], CONTROLS_Y, ENV_POINTS[0][1], CONTROLS_Y + 10), ENV_POINTS[0][2] - screen.stringWidth("Exit") / 2, "Exit"); screen.makeButton(Common::Rect(ENV_POINTS[1][0], CONTROLS_Y, ENV_POINTS[1][1], CONTROLS_Y + 10), ENV_POINTS[1][2] - screen.stringWidth("Load") / 2, "Load"); @@ -92,9 +92,9 @@ void SaveManager::drawInterface() { for (int idx = _savegameIndex; idx < _savegameIndex + 5; ++idx) { - screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10), + screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10), INV_FOREGROUND, "%d.", idx + 1); - screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10), + screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10), INV_FOREGROUND, "%s", _savegames[idx].c_str()); } @@ -317,7 +317,7 @@ void SaveManager::loadGame(int slot) { generateSaveName(slot)); if (!saveFile) return; - + // Load the savaegame header SherlockSavegameHeader header; if (!readSavegameHeader(saveFile, header)) @@ -405,12 +405,12 @@ bool SaveManager::checkGameOnScreen(int slot) { SHERLOCK_SCREEN_HEIGHT - 1), INV_BACKGROUND); for (int idx = _savegameIndex; idx < (_savegameIndex + 5); ++idx) { - screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10), + screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10), INV_FOREGROUND, "%d.", idx + 1); screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10), INV_FOREGROUND, "%s", _savegames[idx].c_str()); } - + screen.slamRect(Common::Rect(3, CONTROLS_Y + 11, 318, SHERLOCK_SCREEN_HEIGHT)); byte color = !_savegameIndex ? COMMAND_NULL : COMMAND_FOREGROUND; @@ -432,7 +432,7 @@ bool SaveManager::getFilename(int slot) { Talk &talk = *_vm->_talk; int xp, yp; bool flag = false; - + screen.buttonPrint(Common::Point(ENV_POINTS[0][2], CONTROLS_Y), COMMAND_NULL, true, "Exit"); screen.buttonPrint(Common::Point(ENV_POINTS[1][2], CONTROLS_Y), COMMAND_NULL, true, "Load"); screen.buttonPrint(Common::Point(ENV_POINTS[2][2], CONTROLS_Y), COMMAND_NULL, true, "Save"); @@ -480,7 +480,7 @@ bool SaveManager::getFilename(int slot) { if (keyState.keycode == Common::KEYCODE_BACKSPACE && saveName.size() > 0) { // Delete character of save name - screen.vgaBar(Common::Rect(xp - screen.charWidth(saveName.lastChar()), yp - 1, + screen.vgaBar(Common::Rect(xp - screen.charWidth(saveName.lastChar()), yp - 1, xp + 8, yp + 9), INV_BACKGROUND); xp -= screen.charWidth(saveName.lastChar()); screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_FOREGROUND); diff --git a/engines/sherlock/scalpel/darts.cpp b/engines/sherlock/scalpel/darts.cpp index 4b48a1dacf..3516a7ae78 100644 --- a/engines/sherlock/scalpel/darts.cpp +++ b/engines/sherlock/scalpel/darts.cpp @@ -45,8 +45,8 @@ enum { PLAYER_COLOR = 11 }; -const char *const OPPONENT_NAMES[5] = { - "Skipper", "Willy", "Micky", "Tom", "Bartender" +const char *const OPPONENT_NAMES[5] = { + "Skipper", "Willy", "Micky", "Tom", "Bartender" }; /*----------------------------------------------------------------*/ @@ -83,7 +83,7 @@ void Darts::playDarts() { do { int score, roundStartScore; roundStartScore = score = playerNumber == 0 ? _dartScore1 : _dartScore2; - + // Show player details showNames(playerNumber); showStatus(playerNumber); @@ -296,7 +296,7 @@ int Darts::throwDart(int dartNum, int computer) { int width, height; events.clearKeyboard(); - + erasePowerBars(); screen.print(Common::Point(DART_INFO_X, DART_INFO_Y), DART_COL_FORE, "Dart # %d", dartNum); @@ -322,10 +322,10 @@ int Darts::throwDart(int dartNum, int computer) { // If it's a computer player, choose a dart destination if (computer) targetNum = getComputerDartDest(computer - 1); - + width = doPowerBar(Common::Point(DARTBARHX, DARTHORIZY), DART_BAR_FORE, targetNum.x, false); height = 101 - doPowerBar(Common::Point(DARTBARVX, DARTHEIGHTY), DART_BAR_FORE, targetNum.y, true); - + // For human players, slight y adjustment if (computer == 0) height += 2; @@ -429,7 +429,7 @@ int Darts::doPowerBar(const Common::Point &pt, byte color, int goToPower, bool i // Reached target power for a computer player done = true; else if (goToPower == 0) { - // Check for pres + // Check for pres if (dartHit()) done = true; } @@ -472,7 +472,7 @@ bool Darts::dartHit() { events.clearKeyboard(); return true; } - + _oldDartButtons = events._pressed; events.setButtonState(); @@ -497,7 +497,7 @@ int Darts::dartScore(const Common::Point &pt) { } /** - * Calculates where a computer player is trying to throw their dart, and choose the actual + * Calculates where a computer player is trying to throw their dart, and choose the actual * point that was hit with some margin of error */ Common::Point Darts::getComputerDartDest(int playerNum) { diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 3fe094bcf4..6ba6b33340 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -28,21 +28,21 @@ namespace Sherlock { namespace Scalpel { #define NUM_PLACES 100 -const int MAP_X[NUM_PLACES] = { - 0, 368, 0, 219, 0, 282, 0, 43, 0, 0, 396, 408, 0, 0, 0, 568, 37, 325, - 28, 0, 263, 36, 148, 469, 342, 143, 443, 229, 298, 0, 157, 260, 432, - 174, 0, 351, 0, 528, 0, 136, 0, 0, 0, 555, 165, 0, 506, 0, 0, 344, 0, 0 +const int MAP_X[NUM_PLACES] = { + 0, 368, 0, 219, 0, 282, 0, 43, 0, 0, 396, 408, 0, 0, 0, 568, 37, 325, + 28, 0, 263, 36, 148, 469, 342, 143, 443, 229, 298, 0, 157, 260, 432, + 174, 0, 351, 0, 528, 0, 136, 0, 0, 0, 555, 165, 0, 506, 0, 0, 344, 0, 0 }; -const int MAP_Y[NUM_PLACES] = { +const int MAP_Y[NUM_PLACES] = { 0, 147, 0, 166, 0, 109, 0, 61, 0, 0, 264, 70, 0, 0, 0, 266, 341, 30, 275, - 0, 294, 146, 311, 230, 184, 268, 133, 94, 207, 0, 142, 142, 330, 255, 0, - 37, 0, 70, 0, 116, 0, 0, 0, 50, 21, 0, 303, 0, 0, 229, 0, 0 + 0, 294, 146, 311, 230, 184, 268, 133, 94, 207, 0, 142, 142, 330, 255, 0, + 37, 0, 70, 0, 116, 0, 0, 0, 50, 21, 0, 303, 0, 0, 229, 0, 0 }; const int MAP_TRANSLATE[NUM_PLACES] = { 0, 0, 0, 1, 0, 2, 0, 3, 4, 0, 4, 6, 0, 0, 0, 8, 9, 10, 11, 0, 12, 13, 14, 7, 15, 16, 17, 18, 19, 0, 20, 21, 22, 23, 0, 24, 0, 25, 0, 26, 0, 0, 0, 27, - 28, 0, 29, 0, 0, 30, 0 + 28, 0, 29, 0, 0, 30, 0 }; const byte MAP_SEQUENCES[3][MAX_FRAME] = { @@ -251,7 +251,7 @@ void ScalpelEngine::showOpening() { */ bool ScalpelEngine::showCityCutscene() { byte palette[PALETTE_SIZE]; - + _sound->playMusic("prolog1.mus"); _titleOverride = "title.lib"; _soundOverride = "title.snd"; @@ -286,7 +286,7 @@ bool ScalpelEngine::showCityCutscene() { ImageFile titleImages("title.vgs", true); _screen->_backBuffer1.copyFrom(*_screen); _screen->_backBuffer2.copyFrom(*_screen); - + // The Lost Files of _screen->_backBuffer1.transBlitFrom(titleImages[0], Common::Point(75, 6)); // Sherlock Holmes @@ -473,7 +473,7 @@ void ScalpelEngine::loadInventory() { inv._holdings = 2; inv.push_back(InventoryItem(0, "Message", "A message requesting help", "_ITEM03A")); inv.push_back(InventoryItem(0, "Holmes Card", "A number of business cards", "_ITEM07A")); - + // Hidden items inv.push_back(InventoryItem(95, "Tickets", "Opera Tickets", "_ITEM10A")); inv.push_back(InventoryItem(138, "Cuff Link", "Cuff Link", "_ITEM04A")); @@ -524,7 +524,7 @@ void ScalpelEngine::startScene() { // 2: Blackwood's capture // 52: Rescuing Anna // 53: Moorehead's death / subway train - // 55: Fade out and exit + // 55: Fade out and exit // 70: Brumwell suicide switch (_scene->_goToScene) { case 2: @@ -678,7 +678,7 @@ void ScalpelEngine::eraseMirror12() { void ScalpelEngine::doMirror12() { People &people = *_people; Common::Point pt((*_people)[AL]._position.x / 100, (*_people)[AL]._position.y / 100); - int frameNum = (*people[AL]._sequences)[people[AL]._sequenceNumber][people[AL]._frameNumber] + + int frameNum = (*people[AL]._sequences)[people[AL]._sequenceNumber][people[AL]._frameNumber] + (*people[AL]._sequences)[people[AL]._sequenceNumber][0] - 2; switch ((*_people)[AL]._sequenceNumber) { @@ -733,17 +733,17 @@ void ScalpelEngine::doMirror12() { _screen->_backBuffer1.transBlitFrom(imageFrame, pt + Common::Point(38, -imageFrame._frame.h - 25), flipped); // Redraw the mirror borders to prevent the drawn image of Holmes from appearing outside of the mirror - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(114, 18), + _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(114, 18), Common::Rect(114, 18, 137, 114)); - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(137, 70), + _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(137, 70), Common::Rect(137, 70, 142, 114)); - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(142, 71), + _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(142, 71), Common::Rect(142, 71, 159, 114)); - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(159, 72), + _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(159, 72), Common::Rect(159, 72, 170, 116)); - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(170, 73), + _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(170, 73), Common::Rect(170, 73, 184, 114)); - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(184, 18), + _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(184, 18), Common::Rect(184, 18, 212, 114)); } } diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 857dff4951..c1a73fee90 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -256,7 +256,7 @@ bool Scene::loadScene(const Common::String &filename) { // Read information Common::SeekableReadStream *infoStream = !_lzwMode ? rrmStream : - decompressLZ(*rrmStream, bgHeader._numImages * 569 + + decompressLZ(*rrmStream, bgHeader._numImages * 569 + bgHeader._descSize + bgHeader._seqSize); _bgShapes.resize(bgHeader._numStructs); @@ -271,7 +271,7 @@ bool Scene::loadScene(const Common::String &filename) { if (bgHeader._seqSize) { _sequenceBuffer.resize(bgHeader._seqSize); infoStream->read(&_sequenceBuffer[0], bgHeader._seqSize); - } + } if (_lzwMode) delete infoStream; @@ -390,7 +390,7 @@ bool Scene::loadScene(const Common::String &filename) { rrmStream->read(screen._cMap, PALETTE_SIZE); for (int idx = 0; idx < PALETTE_SIZE; ++idx) screen._cMap[idx] = VGA_COLOR_TRANS(screen._cMap[idx]); - + Common::copy(screen._cMap, screen._cMap + PALETTE_SIZE, screen._sMap); // Read in the background @@ -522,7 +522,7 @@ void Scene::checkSceneFlags(bool flag) { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; - + if (o._requiredFlag) { if (!_vm->readFlags(_bgShapes[idx]._requiredFlag)) { // Kill object @@ -655,7 +655,7 @@ void Scene::transitionToScene() { if (obj._type != NO_SHAPE) { topLeft += obj._imageFrame->_offset; bottomRight.x = topLeft.x + obj._imageFrame->_frame.w; - bottomRight.y = topLeft.y + obj._imageFrame->_frame.h; + bottomRight.y = topLeft.y + obj._imageFrame->_frame.h; } else { bottomRight = topLeft + obj._noShapeSize; } @@ -768,7 +768,7 @@ void Scene::updateBackground() { // Draw all canimations which are normal and behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if (_canimShapes[idx]._type == ACTIVE_BG_SHAPE && _canimShapes[idx]._misc == NORMAL_BEHIND) - screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, + screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, _canimShapes[idx]._flags & 2); } @@ -778,7 +778,7 @@ void Scene::updateBackground() { player._sequenceNumber == WALK_UPLEFT || player._sequenceNumber == STOP_UPLEFT || player._sequenceNumber == WALK_DOWNRIGHT || player._sequenceNumber == STOP_DOWNRIGHT; - screen._backBuffer->transBlitFrom(*player._imageFrame, Common::Point(player._position.x / 100, + screen._backBuffer->transBlitFrom(*player._imageFrame, Common::Point(player._position.x / 100, player._position.y / 100 - player.frameHeight()), flipped); } @@ -793,7 +793,7 @@ void Scene::updateBackground() { for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if ((_canimShapes[idx]._type == ACTIVE_BG_SHAPE || _canimShapes[idx]._type == STATIC_BG_SHAPE) && _canimShapes[idx]._misc == NORMAL_FORWARD) - screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, + screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, _canimShapes[idx]._flags & 2); } @@ -812,7 +812,7 @@ void Scene::updateBackground() { for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if ((_canimShapes[idx]._type == ACTIVE_BG_SHAPE || _canimShapes[idx]._type == STATIC_BG_SHAPE) && _canimShapes[idx]._misc == FORWARD) - screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, + screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, _canimShapes[idx]._flags & 2); } @@ -966,7 +966,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) { rrmStream->seek(rrmStream->readUint32LE()); // Load the canimation into the cache - Common::SeekableReadStream *imgStream = !_lzwMode ? rrmStream->readStream(cAnim._size) : + Common::SeekableReadStream *imgStream = !_lzwMode ? rrmStream->readStream(cAnim._size) : decompressLZ(*rrmStream, cAnim._size); res.addToCache(fname, *imgStream); @@ -1059,7 +1059,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) { if (playRate < 0) // Reverse direction - set to end sequence cObj._frameNumber = tFrames - 1; - + if (cObj._frameNumber <= 26) gotoCode = cObj._sequences[cObj._frameNumber + 3]; @@ -1108,7 +1108,7 @@ void Scene::doBgAnim() { Common::Point mousePos = events.mousePos(); talk._talkToAbort = false; - + // Animate the mouse cursor if (cursorId >= WAIT) { if (++cursorId > (WAIT + 2)) @@ -1229,7 +1229,7 @@ void Scene::doBgAnim() { people[AL].adjustSprite(); // Flag the bg shapes which need to be redrawn - checkBgShapes(people[AL]._imageFrame, + checkBgShapes(people[AL]._imageFrame, Common::Point(people[AL]._position.x / 100, people[AL]._position.y / 100)); if (_currentScene == 12 && _vm->getGameID() == GType_SerratedScalpel) @@ -1241,7 +1241,7 @@ void Scene::doBgAnim() { if (o._type == ACTIVE_BG_SHAPE && o._misc == BEHIND) screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); } - + // Draw all canimations which are behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; @@ -1335,7 +1335,7 @@ void Scene::doBgAnim() { people[AL]._type = INVALID; } else { screen.flushImage(people[AL]._imageFrame, - Common::Point(people[AL]._position.x / 100, + Common::Point(people[AL]._position.x / 100, people[AL]._position.y / 100 - people[AL].frameHeight()), &people[AL]._oldPosition.x, &people[AL]._oldPosition.y, &people[AL]._oldSize.x, &people[AL]._oldSize.y); @@ -1364,7 +1364,7 @@ void Scene::doBgAnim() { screen.flushImage(people._portrait._imageFrame, people._portrait._position, &people._portrait._oldPosition.x, &people._portrait._oldPosition.y, &people._portrait._oldSize.x, &people._portrait._oldSize.y); - + if (people._portrait._type == REMOVE) people._portrait._type = INVALID; } @@ -1410,7 +1410,7 @@ void Scene::doBgAnim() { screen.resetDisplayBounds(); // Check if the method was called for calling a portrait, and a talk was - // interrupting it. This talk file would not have been executed at the time, + // interrupting it. This talk file would not have been executed at the time, // since we needed to finish the 'doBgAnim' to finish clearing the portrait if (people._clearingThePortrait && talk._scriptMoreFlag == 3) { // Reset the flags and call to talk diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 1f56261150..72045a83fb 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -222,12 +222,12 @@ void Screen::randomTransition() { if (offset < (SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCREEN_HEIGHT)) *((byte *)getPixels() + offset) = *((const byte *)_backBuffer->getPixels() + offset); - + if (idx != 0 && (idx % 100) == 0) { // Ensure there's a full screen dirty rect for the next frame update if (_dirtyRects.empty()) addDirtyRect(Common::Rect(0, 0, this->w, this->h)); - + events.pollEvents(); events.delay(1); } @@ -245,10 +245,10 @@ void Screen::verticalTransition() { byte table[SHERLOCK_SCREEN_WIDTH]; Common::fill(&table[0], &table[SHERLOCK_SCREEN_WIDTH], 0); - - for (int yp = 0; yp < SHERLOCK_SCREEN_HEIGHT; ++yp) { + + for (int yp = 0; yp < SHERLOCK_SCREEN_HEIGHT; ++yp) { for (int xp = 0; xp < SHERLOCK_SCREEN_WIDTH; ++xp) { - int temp = (table[xp] >= 197) ? SHERLOCK_SCREEN_HEIGHT - table[xp] : + int temp = (table[xp] >= 197) ? SHERLOCK_SCREEN_HEIGHT - table[xp] : _vm->getRandomNumber(3) + 1; if (temp) { @@ -384,7 +384,7 @@ void Screen::gPrint(const Common::Point &pt, byte color, const char *format, ... int Screen::stringWidth(const Common::String &str) { int width = 0; - for (const char *c = str.c_str(); *c; ++c) + for (const char *c = str.c_str(); *c; ++c) width += charWidth(*c); return width; @@ -442,7 +442,7 @@ void Screen::makeButton(const Common::Rect &bounds, int textX, bb.fillRect(Common::Rect(bounds.left + 1, bounds.top + 1, bounds.right - 1, bounds.bottom - 1), BUTTON_MIDDLE); gPrint(Common::Point(textX, bounds.top), COMMAND_HIGHLIGHTED, "%c", str[0]); - gPrint(Common::Point(textX + charWidth(str[0]), bounds.top), + gPrint(Common::Point(textX + charWidth(str[0]), bounds.top), COMMAND_FOREGROUND, "%s", str.c_str() + 1); } @@ -481,7 +481,7 @@ void Screen::makePanel(const Common::Rect &r) { _backBuffer->hLine(r.left + 1, r.top + 1, r.right - 3, BUTTON_TOP); _backBuffer->vLine(r.left, r.top, r.bottom - 1, BUTTON_TOP); _backBuffer->vLine(r.left + 1, r.top + 1, r.bottom - 2, BUTTON_TOP); - + _backBuffer->vLine(r.right - 1, r.top, r.bottom - 1, BUTTON_BOTTOM); _backBuffer->vLine(r.right - 2, r.top + 1, r.bottom - 2, BUTTON_BOTTOM); _backBuffer->hLine(r.left, r.bottom - 1, r.right - 1, BUTTON_BOTTOM); diff --git a/engines/sherlock/settings.cpp b/engines/sherlock/settings.cpp index e19aefd9c5..2a4d332edf 100644 --- a/engines/sherlock/settings.cpp +++ b/engines/sherlock/settings.cpp @@ -25,7 +25,7 @@ namespace Sherlock { -const int SETUP_POINTS[12][4] = { +const int SETUP_POINTS[12][4] = { { 4, 154, 101, 53 }, // Exit { 4, 165, 101, 53 }, // Music Toggle { 219, 165, 316, 268 }, // Voice Toggle @@ -76,40 +76,40 @@ void Settings::drawInteface(bool flag) { SETUP_POINTS[0][3] - screen.stringWidth("Exit") / 2, "Exit"); tempStr = Common::String::format("Music %s", SETUP_STRS0[sound._music]); - screen.makeButton(Common::Rect(SETUP_POINTS[1][0], SETUP_POINTS[1][1], SETUP_POINTS[1][2], SETUP_POINTS[1][1] + 10), + screen.makeButton(Common::Rect(SETUP_POINTS[1][0], SETUP_POINTS[1][1], SETUP_POINTS[1][2], SETUP_POINTS[1][1] + 10), SETUP_POINTS[1][3] - screen.stringWidth(tempStr) / 2, tempStr); tempStr = Common::String::format("Voices %s", SETUP_STRS0[sound._voices]); - screen.makeButton(Common::Rect(SETUP_POINTS[2][0], SETUP_POINTS[2][1], SETUP_POINTS[2][2], SETUP_POINTS[2][1] + 10), + screen.makeButton(Common::Rect(SETUP_POINTS[2][0], SETUP_POINTS[2][1], SETUP_POINTS[2][2], SETUP_POINTS[2][1] + 10), SETUP_POINTS[2][3] - screen.stringWidth(tempStr) / 2, tempStr); tempStr = Common::String::format("Sound Effects %s", SETUP_STRS0[sound._digitized]); - screen.makeButton(Common::Rect(SETUP_POINTS[3][0], SETUP_POINTS[3][1], SETUP_POINTS[3][2], SETUP_POINTS[3][1] + 10), + screen.makeButton(Common::Rect(SETUP_POINTS[3][0], SETUP_POINTS[3][1], SETUP_POINTS[3][2], SETUP_POINTS[3][1] + 10), SETUP_POINTS[3][3] - screen.stringWidth(tempStr) / 2, tempStr); tempStr = Common::String::format("Auto Help %s", SETUP_STRS5[ui._helpStyle]); - screen.makeButton(Common::Rect(SETUP_POINTS[4][0], SETUP_POINTS[4][1], SETUP_POINTS[4][2], SETUP_POINTS[4][1] + 10), + screen.makeButton(Common::Rect(SETUP_POINTS[4][0], SETUP_POINTS[4][1], SETUP_POINTS[4][2], SETUP_POINTS[4][1] + 10), SETUP_POINTS[4][3] - screen.stringWidth(tempStr) / 2, tempStr); - screen.makeButton(Common::Rect(SETUP_POINTS[5][0], SETUP_POINTS[5][1], SETUP_POINTS[5][2], SETUP_POINTS[5][1] + 10), + screen.makeButton(Common::Rect(SETUP_POINTS[5][0], SETUP_POINTS[5][1], SETUP_POINTS[5][2], SETUP_POINTS[5][1] + 10), SETUP_POINTS[5][3] - screen.stringWidth("New Font Style") / 2, "New Font Style"); // WORKAROUND: We don't support the joystick in ScummVM, so draw the next two buttons as disabled tempStr = "Joystick Off"; - screen.makeButton(Common::Rect(SETUP_POINTS[6][0], SETUP_POINTS[6][1], SETUP_POINTS[6][2], SETUP_POINTS[6][1] + 10), + screen.makeButton(Common::Rect(SETUP_POINTS[6][0], SETUP_POINTS[6][1], SETUP_POINTS[6][2], SETUP_POINTS[6][1] + 10), SETUP_POINTS[6][3] - screen.stringWidth(tempStr) / 2, tempStr); screen.buttonPrint(Common::Point(SETUP_POINTS[6][3], SETUP_POINTS[6][1]), COMMAND_NULL, false, tempStr); tempStr = "Calibrate Joystick"; - screen.makeButton(Common::Rect(SETUP_POINTS[7][0], SETUP_POINTS[7][1], SETUP_POINTS[7][2], SETUP_POINTS[7][1] + 10), + screen.makeButton(Common::Rect(SETUP_POINTS[7][0], SETUP_POINTS[7][1], SETUP_POINTS[7][2], SETUP_POINTS[7][1] + 10), SETUP_POINTS[7][3] - screen.stringWidth(tempStr) / 2, tempStr); screen.buttonPrint(Common::Point(SETUP_POINTS[7][3], SETUP_POINTS[7][1]), COMMAND_NULL, false, tempStr); tempStr = Common::String::format("Fade %s", screen._fadeStyle ? "by Pixel" : "Directly"); - screen.makeButton(Common::Rect(SETUP_POINTS[8][0], SETUP_POINTS[8][1], SETUP_POINTS[8][2], SETUP_POINTS[8][1] + 10), + screen.makeButton(Common::Rect(SETUP_POINTS[8][0], SETUP_POINTS[8][1], SETUP_POINTS[8][2], SETUP_POINTS[8][1] + 10), SETUP_POINTS[8][3] - screen.stringWidth(tempStr) / 2, tempStr); - + tempStr = Common::String::format("Windows %s", ui._windowStyle ? "Slide" : "Appear"); - screen.makeButton(Common::Rect(SETUP_POINTS[9][0], SETUP_POINTS[9][1], SETUP_POINTS[9][2], SETUP_POINTS[9][1] + 10), + screen.makeButton(Common::Rect(SETUP_POINTS[9][0], SETUP_POINTS[9][1], SETUP_POINTS[9][2], SETUP_POINTS[9][1] + 10), SETUP_POINTS[9][3] - screen.stringWidth(tempStr) / 2, tempStr); tempStr = Common::String::format("Portraits %s", SETUP_STRS0[people._portraitsOn]); @@ -121,7 +121,7 @@ void Settings::drawInteface(bool flag) { SETUP_POINTS[11][3] - screen.stringWidth(tempStr) / 2, tempStr); screen.buttonPrint(Common::Point(SETUP_POINTS[11][3], SETUP_POINTS[11][1]), COMMAND_NULL, false, tempStr); - // Show the window immediately, or slide it on-screen + // Show the window immediately, or slide it on-screen if (!flag) { if (!ui._windowStyle) { screen.slamRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); @@ -150,7 +150,7 @@ int Settings::drawButtons(const Common::Point &pt, int _key) { for (int idx = 0; idx < 12; ++idx) { if ((pt.x > SETUP_POINTS[idx][0] && pt.x < SETUP_POINTS[idx][2] && pt.y > SETUP_POINTS[idx][1] - && pt.y < (SETUP_POINTS[idx][1] + 10) && (events._released || events._released)) + && pt.y < (SETUP_POINTS[idx][1] + 10) && (events._released || events._released)) || (_key == SETUP_NAMES[idx][0])) { found = idx; color = COMMAND_HIGHLIGHTED; @@ -160,23 +160,23 @@ int Settings::drawButtons(const Common::Point &pt, int _key) { // Print the button text switch (idx) { - case 1: + case 1: tempStr = Common::String::format("Music %s", SETUP_STRS0[sound._music]); screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); break; - case 2: + case 2: tempStr = Common::String::format("Voices %s", SETUP_STRS0[sound._voices]); screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); break; - case 3: + case 3: tempStr = Common::String::format("Sound Effects %s", SETUP_STRS0[sound._digitized]); screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); break; - case 4: + case 4: tempStr = Common::String::format("Auto Help %s", SETUP_STRS2[ui._helpStyle]); screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); break; - case 6: + case 6: tempStr = "Joystick Off"; screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), COMMAND_NULL, true, tempStr); break; @@ -184,23 +184,23 @@ int Settings::drawButtons(const Common::Point &pt, int _key) { tempStr = "Calibrate Joystick"; screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), COMMAND_NULL, true, tempStr); break; - case 8: + case 8: tempStr = Common::String::format("Fade %s", SETUP_STRS1[screen._fadeStyle]); screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); break; - case 9: + case 9: tempStr = Common::String::format("Windows %s", SETUP_STRS3[ui._windowStyle]); screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); break; - case 10: + case 10: tempStr = Common::String::format("Portraits %s", SETUP_STRS0[people._portraitsOn]); screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); break; - case 11: + case 11: tempStr = "Key Pad Slow"; screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), COMMAND_NULL, true, tempStr); break; - default: + default: screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, SETUP_NAMES[idx]); break; } diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 5a73b4fd1d..1a6e84b186 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -119,7 +119,7 @@ Common::Error SherlockEngine::run() { } while (!shouldQuit()) { - // Prepare for scene, and handle any game-specific scenes. This allows + // Prepare for scene, and handle any game-specific scenes. This allows // for game specific cutscenes or mini-games that aren't standard scenes startScene(); if (shouldQuit()) @@ -131,7 +131,7 @@ Common::Error SherlockEngine::run() { // Reset the data for the player character (Sherlock) _people->reset(); - // Initialize and load the scene. + // Initialize and load the scene. _scene->selectScene(); // Scene handling loop diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index 1fd4c29b12..5c2e8808ee 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -64,7 +64,7 @@ public: int loadSong(int songNumber); void startSong(); void freeSong(); - + void playMusic(const Common::String &name); void stopMusic(); void stopSndFuncPtr(int v1, int v2); diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index b1f4d4e546..55a79f8170 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -86,7 +86,7 @@ TalkSequences::TalkSequences(const byte *data) { } void TalkSequences::clear() { - Common::fill(&_data[0], &_data[MAX_TALK_SEQUENCES], 0); + Common::fill(&_data[0], &_data[MAX_TALK_SEQUENCES], 0); } /*----------------------------------------------------------------*/ @@ -121,10 +121,10 @@ void Talk::setSequences(const byte *talkSequences, const byte *stillSequences, i /** * Called whenever a conversation or item script needs to be run. For standard conversations, - * it opens up a description window similar to how 'talk' does, but shows a 'reply' directly - * instead of waiting for a statement option. + * it opens up a description window similar to how 'talk' does, but shows a 'reply' directly + * instead of waiting for a statement option. * @remarks It seems that at some point, all item scripts were set up to use this as well. - * In their case, the conversation display is simply suppressed, and control is passed on to + * In their case, the conversation display is simply suppressed, and control is passed on to * doScript to implement whatever action is required. */ void Talk::talkTo(const Common::String &filename) { @@ -185,7 +185,7 @@ void Talk::talkTo(const Common::String &filename) { SequenceEntry &ss = _savedSequences[idx]; for (uint idx2 = 0; idx2 < ss._sequences.size(); ++idx2) scene._bgShapes[ss._objNum]._sequences[idx2] = ss._sequences[idx2]; - + // Reset the object's frame to the beginning of the sequence scene._bgShapes[ss._objNum]._frameNumber = 0; } @@ -314,7 +314,7 @@ void Talk::talkTo(const Common::String &filename) { ui.clearInfo(); } - // Handle replies until there's no further linked file, + // Handle replies until there's no further linked file, // or the link file isn't a reply first cnversation while (!_vm->shouldQuit()) { clearSequences(); @@ -336,7 +336,7 @@ void Talk::talkTo(const Common::String &filename) { setTalkMap(); } - + // Check for a linked file if (!statement._linkFile.empty() && !_scriptMoreFlag) { Common::String linkFilename = statement._linkFile; @@ -385,7 +385,7 @@ void Talk::talkTo(const Common::String &filename) { screen.buttonPrint(Common::Point(119, CONTROLS_Y), color, true, "Exit"); } else { screen.buttonPrint(Common::Point(119, CONTROLS_Y), color, false, "Exit"); - + if (!ui._windowStyle) { screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); @@ -451,7 +451,7 @@ void Talk::talkTo(const Common::String &filename) { /** * Main method for handling conversations when a character to talk to has been - * selected. It will make Holmes walk to the person to talk to, draws the + * selected. It will make Holmes walk to the person to talk to, draws the * interface window for the conversation and passes on control to give the * player a list of options to make a selection from */ @@ -497,7 +497,7 @@ void Talk::talk(int objNum) { events.setCursor(WAIT); if (obj._lookPosition.y != 0) // Need to walk to character first - people.walkToCoords(Common::Point(obj._lookPosition.x, obj._lookPosition.y * 100), + people.walkToCoords(Common::Point(obj._lookPosition.x, obj._lookPosition.y * 100), obj._lookFacing); events.setCursor(ARROW); @@ -587,7 +587,7 @@ void Talk::loadTalkFile(const Common::String &filename) { _statements.resize(talkStream->readByte()); for (uint idx = 0; idx < _statements.size(); ++idx) _statements[idx].synchronize(*talkStream); - + delete talkStream; if (!sound._voices) @@ -607,7 +607,7 @@ void Talk::stripVoiceCommands() { if (statement._reply[idx] == SFX_COMMAND) { // Replace instruction character with a space, and delete the // rest of the name following it - statement._reply = Common::String(statement._reply.c_str(), + statement._reply = Common::String(statement._reply.c_str(), statement._reply.c_str() + idx) + " " + Common::String(statement._reply.c_str() + 9); } @@ -673,7 +673,7 @@ void Talk::drawInterface() { } /** - * Display a list of statements in a window at the bottom of the scren that the + * Display a list of statements in a window at the bottom of the scren that the * player can select from. */ bool Talk::displayTalk(bool slamIt) { @@ -681,7 +681,7 @@ bool Talk::displayTalk(bool slamIt) { int yp = CONTROLS_Y + 14; int lineY = -1; _moreTalkDown = _moreTalkUp = false; - + for (uint idx = 0; idx < _statements.size(); ++idx) { _statements[idx]._talkPos.top = _statements[idx]._talkPos.bottom = -1; } @@ -708,7 +708,7 @@ bool Talk::displayTalk(bool slamIt) { screen.vgaBar(Common::Rect(5, CONTROLS_Y + 11, 15, CONTROLS_Y + 22), INV_BACKGROUND); } else { screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_NULL, false, "Up"); - screen._backBuffer1.fillRect(Common::Rect(5, CONTROLS_Y + 11, + screen._backBuffer1.fillRect(Common::Rect(5, CONTROLS_Y + 11, 15, CONTROLS_Y + 22), INV_BACKGROUND); } } @@ -720,9 +720,9 @@ bool Talk::displayTalk(bool slamIt) { if (statement._talkMap != -1) { bool flag = _talkHistory[_converseNum][idx]; - lineY = talkLine(idx, statement._talkMap, flag ? TALK_NULL : INV_FOREGROUND, + lineY = talkLine(idx, statement._talkMap, flag ? TALK_NULL : INV_FOREGROUND, yp, slamIt); - + if (lineY != -1) { statement._talkPos.top = yp; yp = lineY; @@ -834,7 +834,7 @@ int Talk::talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt // Move to next line, if any lineY += 9; lineStartP = lineEndP; - + if (!*lineEndP) break; } else { @@ -911,7 +911,7 @@ void Talk::pushSequence(int speaker) { seqEntry._seqTo = obj._seqTo; } } - + _sequenceStack.push(seqEntry); if (_scriptStack.size() >= 5) error("script stack overflow"); @@ -923,7 +923,7 @@ void Talk::pushSequence(int speaker) { void Talk::setSequence(int speaker) { People &people = *_vm->_people; Scene &scene = *_vm->_scene; - + // If no speaker is specified, then nothing needs to be done if (speaker == -1) return; @@ -965,7 +965,7 @@ void Talk::setStillSeq(int speaker) { int objNum = people.findSpeaker(speaker); if (objNum != -1) { Object &obj = scene._bgShapes[objNum]; - + if (obj._seqSize < MAX_TALK_SEQUENCES) { warning("Tried to copy too few still frames"); } else { @@ -1206,7 +1206,7 @@ void Talk::doScript(const Common::String &script) { ++str; _scriptCurrentIndex = str - scriptStart; - people.walkToCoords(Common::Point(((str[0] - 1) * 256 + str[1] - 1) * 100, + people.walkToCoords(Common::Point(((str[0] - 1) * 256 + str[1] - 1) * 100, str[2] * 100), str[3] - 1); if (_talkToAbort) return; @@ -1270,7 +1270,7 @@ void Talk::doScript(const Common::String &script) { ++str; break; } - + case SFX_COMMAND: ++str; if (sound._voices) { @@ -1305,7 +1305,7 @@ void Talk::doScript(const Common::String &script) { int flag = (str[0] - 1) * 256 + str[1] - 1 - (str[1] == 1 ? 1 : 0); ++str; wait = 0; - + bool result = flag < 0x8000; if (_vm->readFlags(flag & 0x7fff) != result) { do { @@ -1761,7 +1761,7 @@ void Talk::popStack() { void Talk::synchronize(Common::Serializer &s) { for (int idx = 0; idx < MAX_TALK_FILES; ++idx) { TalkHistoryEntry &he = _talkHistory[idx]; - + for (int flag = 0; flag < 16; ++flag) s.syncAsByte(he._data[flag]); } diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index a134b95196..f048e280a8 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -27,7 +27,7 @@ namespace Sherlock { // Main user interface menu control locations -const int MENU_POINTS[12][4] = { +const int MENU_POINTS[12][4] = { { 13, 153, 72, 165 }, { 13, 169, 72, 181 }, { 13, 185, 72, 197 }, @@ -39,11 +39,11 @@ const int MENU_POINTS[12][4] = { { 165, 185, 233, 197 }, { 249, 153, 305, 165 }, { 249, 169, 305, 181 }, - { 249, 185, 305, 197 } + { 249, 185, 305, 197 } }; // Inventory control locations */ -const int INVENTORY_POINTS[8][3] = { +const int INVENTORY_POINTS[8][3] = { { 4, 50, 29 }, { 52, 99, 77 }, { 101, 140, 123 }, @@ -51,7 +51,7 @@ const int INVENTORY_POINTS[8][3] = { { 189, 219, 198 }, { 221, 251, 234 }, { 253, 283, 266 }, - { 285, 315, 294 } + { 285, 315, 294 } }; const char COMMANDS[13] = "LMTPOCIUGJFS"; @@ -59,23 +59,23 @@ const char INVENTORY_COMMANDS[9] = { "ELUG-+,." }; const char *const PRESS_KEY_FOR_MORE = "Press any Key for More."; const char *const PRESS_KEY_TO_CONTINUE = "Press any Key to Continue."; -const char *const MOPEN[] = { - "This cannot be opened", "It is already open", "It is locked", "Wait for Watson", " ", "." +const char *const MOPEN[] = { + "This cannot be opened", "It is already open", "It is locked", "Wait for Watson", " ", "." }; -const char *const MCLOSE[] = { - "This cannot be closed", "It is already closed", "The safe door is in the way" +const char *const MCLOSE[] = { + "This cannot be closed", "It is already closed", "The safe door is in the way" }; -const char *const MMOVE[] = { +const char *const MMOVE[] = { "This cannot be moved", "It is bolted to the floor", "It is too heavy", "The other crate is in the way" }; const char *const MPICK[] = { "Nothing of interest here", "It is bolted down", "It is too big to carry", "It is too heavy", - "I think a girl would be more your type", "Those flowers belong to Penny", "She's far too young for you!", - "I think a girl would be more your type!", "Government property for official use only" + "I think a girl would be more your type", "Those flowers belong to Penny", "She's far too young for you!", + "I think a girl would be more your type!", "Government property for official use only" }; -const char *const MUSE[] = { - "You can't do that", "It had no effect", "You can't reach it", "OK, the door looks bigger! Happy?", - "Doors don't smoke" +const char *const MUSE[] = { + "You can't do that", "It had no effect", "You can't reach it", "OK, the door looks bigger! Happy?", + "Doors don't smoke" }; /*----------------------------------------------------------------*/ @@ -198,7 +198,7 @@ void UserInterface::handleInput() { } else if (pt.y < CONTROLS_Y && ((events._rightReleased && _helpStyle) || (events._released && !_helpStyle)) && (_bgFound != -1 && _bgFound < 1000) && - (scene._bgShapes[_bgFound]._defaultCommand || + (scene._bgShapes[_bgFound]._defaultCommand || !scene._bgShapes[_bgFound]._description.empty())) { // If there is no default command, set it to Look if (scene._bgShapes[_bgFound]._defaultCommand) @@ -208,7 +208,7 @@ void UserInterface::handleInput() { events._released = true; events._pressed = events._oldButtons = false; _help = _oldHelp = -1; - + if (_menuMode == LOOK_MODE) { // Set the flag to tell the game that this was a right-click // call to look and should exit without the look button being pressed @@ -323,7 +323,7 @@ void UserInterface::handleInput() { // // Do input processing // - if (events._pressed || events._released || events._rightPressed || + if (events._pressed || events._released || events._rightPressed || _keycode != Common::KEYCODE_INVALID || _pause) { if (((events._released && (_helpStyle || _help == -1)) || (events._rightReleased && !_helpStyle)) && (pt.y <= CONTROLS_Y) && (_menuMode == STD_MODE)) { @@ -390,7 +390,7 @@ void UserInterface::handleInput() { // As long as there isn't an open window, do main input processing. // Windows are opened when in TALK, USE, INV, and GIVE modes - if ((!_windowOpen && !_menuCounter && pt.y > CONTROLS_Y) || + if ((!_windowOpen && !_menuCounter && pt.y > CONTROLS_Y) || _keycode != Common::KEYCODE_INVALID) { if (events._pressed || events._released || _pause || _keycode != Common::KEYCODE_INVALID) @@ -426,7 +426,7 @@ void UserInterface::restoreButton(int num) { screen._backBuffer1.blitFrom(screen._backBuffer2, pt, Common::Rect(pt.x, pt.y, pt.x + 90, pt.y + 19)); screen.slamArea(pt.x, pt.y, pt.x + frame.w, pt.y + frame.h); - + if (!_menuCounter) { _infoFlag++; clearInfo(); @@ -461,7 +461,7 @@ void UserInterface::pushButton(int num) { */ void UserInterface::toggleButton(int num) { Screen &screen = *_vm->_screen; - + if (_menuMode != (num + 1)) { _menuMode = (MenuMode)(num + 1); _oldKey = COMMANDS[num]; @@ -534,7 +534,7 @@ void UserInterface::examine() { if (pt.y < (CONTROLS_Y + 9)) { Object &obj = scene._bgShapes[_bgFound]; - + if (obj._lookcAnim != 0) { int canimSpeed = ((obj._lookcAnim & 0xe0) >> 5) + 1; scene._cAnimFramePause = obj._lookFrames; @@ -669,13 +669,13 @@ void UserInterface::lookScreen(const Common::Point &pt) { } int xStart = (SHERLOCK_SCREEN_WIDTH - x) / 2; - screen.print(Common::Point(xStart, INFO_LINE + 1), + screen.print(Common::Point(xStart, INFO_LINE + 1), INFO_FOREGROUND, "Give "); - screen.print(Common::Point(xStart + width, INFO_LINE + 1), + screen.print(Common::Point(xStart + width, INFO_LINE + 1), TALK_FOREGROUND, inv[_selector]._name.c_str()); - screen.print(Common::Point(xStart + width + width1, INFO_LINE + 1), + screen.print(Common::Point(xStart + width + width1, INFO_LINE + 1), INFO_FOREGROUND, " to "); - screen.print(Common::Point(xStart + width + width1 + width2, INFO_LINE + 1), + screen.print(Common::Point(xStart + width + width1 + width2, INFO_LINE + 1), INFO_FOREGROUND, tempStr.c_str()); } } else { @@ -795,16 +795,16 @@ void UserInterface::doEnvControl() { if (_selector != _oldSelector) { if (_oldSelector != -1 && _oldSelector >= saves._savegameIndex && _oldSelector < (saves._savegameIndex + 5)) { - screen.print(Common::Point(6, CONTROLS_Y + 12 + (_oldSelector - saves._savegameIndex) * 10), + screen.print(Common::Point(6, CONTROLS_Y + 12 + (_oldSelector - saves._savegameIndex) * 10), INV_FOREGROUND, "%d.", _oldSelector + 1); - screen.print(Common::Point(24, CONTROLS_Y + 12 + (_oldSelector - saves._savegameIndex) * 10), + screen.print(Common::Point(24, CONTROLS_Y + 12 + (_oldSelector - saves._savegameIndex) * 10), INV_FOREGROUND, "%s", saves._savegames[_oldSelector].c_str()); } if (_selector != -1) { - screen.print(Common::Point(6, CONTROLS_Y + 12 + (_selector - saves._savegameIndex) * 10), + screen.print(Common::Point(6, CONTROLS_Y + 12 + (_selector - saves._savegameIndex) * 10), TALK_FOREGROUND, "%d.", _selector + 1); - screen.print(Common::Point(24, CONTROLS_Y + 12 + (_selector - saves._savegameIndex) * 10), + screen.print(Common::Point(24, CONTROLS_Y + 12 + (_selector - saves._savegameIndex) * 10), TALK_FOREGROUND, "%s", saves._savegames[_selector].c_str()); } @@ -815,7 +815,7 @@ void UserInterface::doEnvControl() { if ((found == 0 && events._released) || _key == 'E') { banishWindow(); _windowBounds.top = CONTROLS_Y1; - + events._pressed = events._released = _keyboardInput = false; _keycode = Common::KEYCODE_INVALID; } else if ((found == 1 && events._released) || _key == 'L') { @@ -839,13 +839,13 @@ void UserInterface::doEnvControl() { _keyboardInput = false; } else { if (!talk._talkToAbort) { - screen._backBuffer1.fillRect(Common::Rect(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, + screen._backBuffer1.fillRect(Common::Rect(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y + 20 + (_selector - saves._savegameIndex) * 10), INV_BACKGROUND); - screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), INV_FOREGROUND, + screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), INV_FOREGROUND, "%d.", _selector + 1); - screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), INV_FOREGROUND, + screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), INV_FOREGROUND, "%s", saves._savegames[_selector].c_str()); - + screen.slamArea(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, 311, 10); _selector = _oldSelector = -1; } @@ -887,7 +887,7 @@ void UserInterface::doEnvControl() { bool moreKeys; do { saves._savegameIndex++; - screen._backBuffer1.fillRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, + screen._backBuffer1.fillRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT - 1), INV_BACKGROUND); for (int idx = saves._savegameIndex; idx < (saves._savegameIndex + 5); ++idx) { @@ -898,10 +898,10 @@ void UserInterface::doEnvControl() { screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, "%d.", idx + 1); - screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, + screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, "%s", saves._savegames[idx].c_str()); } - + screen.slamRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT)); color = (!saves._savegameIndex) ? COMMAND_NULL : COMMAND_FOREGROUND; @@ -1007,11 +1007,11 @@ void UserInterface::doEnvControl() { _keyboardInput = false; } else { if (!talk._talkToAbort) { - screen._backBuffer1.fillRect(Common::Rect(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, + screen._backBuffer1.fillRect(Common::Rect(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, 317, CONTROLS_Y + 20 + (_selector - saves._savegameIndex) * 10), INV_BACKGROUND); - screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), + screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), INV_FOREGROUND, "%d.", _selector + 1); - screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), + screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), INV_FOREGROUND, "%s", saves._savegames[_selector].c_str()); screen.slamArea(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, 311, 10); _selector = _oldSelector = -1; @@ -1201,14 +1201,14 @@ void UserInterface::doInvControl() { // If it's -1, then no inventory item is highlighted yet. Otherwise, // an object in the scene has been clicked. - if (_selector != -1 && inv._invMode == INVMODE_LOOK + if (_selector != -1 && inv._invMode == INVMODE_LOOK && mousePos.y >(CONTROLS_Y1 + 11)) inv.doInvJF(); if (talk._talkToAbort) return; - // Now check for the Use and Give actions. If inv_mode is 3, + // Now check for the Use and Give actions. If inv_mode is 3, // that means GIVE is in effect, _selector is the object being // given, and _find is the target. // The same applies to USE, except if _selector is -1, then USE @@ -1242,7 +1242,7 @@ void UserInterface::doInvControl() { else // Now inv object has been highlighted checkUseAction(&scene._bgShapes[_find]._use[0], "*SELF*", MUSE, _find, temp - 2); - + _selector = _oldSelector = -1; } } @@ -1251,14 +1251,14 @@ void UserInterface::doInvControl() { } /** - * Handles waiting whilst an object's description window is open. + * Handles waiting whilst an object's description window is open. */ void UserInterface::doLookControl() { Events &events = *_vm->_events; Inventory &inv = *_vm->_inventory; Screen &screen = *_vm->_screen; - _key = _oldKey = -1; + _key = _oldKey = -1; _keyboardInput = _keycode != Common::KEYCODE_INVALID; if (events._released || events._rightReleased || _keyboardInput) { @@ -1268,7 +1268,7 @@ void UserInterface::doLookControl() { if (!_descStr.empty()) { printObjectDesc(_descStr, false); } else if (!_lookHelp) { - // Need to close the window and depress the Look button + // Need to close the window and depress the Look button Common::Point pt(MENU_POINTS[0][0], MENU_POINTS[0][1]); screen._backBuffer2.blitFrom((*_controls)[0]._frame, pt); banishWindow(true); @@ -1348,7 +1348,7 @@ void UserInterface::doMainControl() { if (_temp == 12) _key = -1; - + if (events._rightPressed) { _temp = 12; _key = -1; @@ -1356,7 +1356,7 @@ void UserInterface::doMainControl() { } else if (!events._released) { _key = -1; } - + // Check if the button being pointed to has changed if (_oldKey != _key && !_windowOpen) { // Clear the info line @@ -1431,7 +1431,7 @@ void UserInterface::doMainControl() { // Display the dialog saves.drawInterface(); - + _selector = _oldSelector = -1; _windowOpen = true; break; @@ -1550,7 +1550,7 @@ void UserInterface::doTalkControl() { screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Exit"); else if (_endKeyActive) screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_FOREGROUND, true, "Exit"); - + if (mousePos.x > 140 && mousePos.x < 170 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 10) && talk._moreTalkUp) screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Up"); else if (talk._moreTalkUp) @@ -1613,13 +1613,13 @@ void UserInterface::doTalkControl() { } if (events._released || _keyboardInput) { - if (((Common::Rect(99, CONTROLS_Y, 138, CONTROLS_Y + 10).contains(mousePos) && events._released) + if (((Common::Rect(99, CONTROLS_Y, 138, CONTROLS_Y + 10).contains(mousePos) && events._released) || _key == 'E') && _endKeyActive) { talk.freeTalkVars(); talk.pullSequence(); banishWindow(); _windowBounds.top = CONTROLS_Y1; - } else if (((Common::Rect(140, CONTROLS_Y, 179, CONTROLS_Y + 10).contains(mousePos) && events._released) + } else if (((Common::Rect(140, CONTROLS_Y, 179, CONTROLS_Y + 10).contains(mousePos) && events._released) || _key == 'U') && talk._moreTalkUp) { while (talk._statements[--talk._talkIndex]._talkMap == -1) ; @@ -1655,7 +1655,7 @@ void UserInterface::doTalkControl() { // Flag the response as having been used talk._talkHistory[talk._converseNum][_selector] = true; - + clearWindow(); screen.print(Common::Point(16, CONTROLS_Y + 12), TALK_FOREGROUND, "Sherlock Holmes"); talk.talkLine(_selector + 128, talk._statements[_selector]._talkMap, COMMAND_FOREGROUND, CONTROLS_Y + 21, true); @@ -1784,7 +1784,7 @@ void UserInterface::doTalkControl() { /** * Handles events when the Journal is active. * @remarks Whilst this would in theory be better in the Journal class, since it displays in - * the user interface, it uses so many internal UI fields, that it sort of made some sense + * the user interface, it uses so many internal UI fields, that it sort of made some sense * to put it in the UserInterface class. */ void UserInterface::journalControl() { @@ -1801,7 +1801,7 @@ void UserInterface::journalControl() { do { _key = -1; events.setButtonState(); - + // Handle keypresses if (events.kbHit()) { Common::KeyState keyState = events.getKey(); @@ -1859,7 +1859,7 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { if (!_invLookFlag) { // See if this look was called by a right button click or not if (!_lookHelp) { - // If it wasn't a right button click, then we need depress + // If it wasn't a right button click, then we need depress // the look button before we close the window. So save a copy of the // menu area, and draw the controls onto it Surface tempSurface((*_controls)[0]._frame.w, (*_controls)[0]._frame.h); @@ -1945,7 +1945,7 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { do { width += screen.charWidth(*msgP++); } while (width < 300 && *msgP); - + if (*msgP) --msgP; else @@ -2036,7 +2036,7 @@ void UserInterface::summonWindow(const Surface &bgSurface, bool slideUp) { } else { // Gradually slide down the display of the window for (int idx = 1; idx <= bgSurface.h; idx += 2) { - screen._backBuffer->blitFrom(bgSurface, + screen._backBuffer->blitFrom(bgSurface, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h), Common::Rect(0, bgSurface.h - idx, bgSurface.w, bgSurface.h)); screen.slamRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h, @@ -2047,7 +2047,7 @@ void UserInterface::summonWindow(const Surface &bgSurface, bool slideUp) { } // Final display of the entire window - screen._backBuffer->blitFrom(bgSurface, Common::Point(0, + screen._backBuffer->blitFrom(bgSurface, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h), Common::Rect(0, 0, bgSurface.w, bgSurface.h)); screen.slamArea(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h, bgSurface.w, bgSurface.h); @@ -2100,7 +2100,7 @@ void UserInterface::banishWindow(bool slideUp) { Common::Point(0, CONTROLS_Y), Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y + idx)); - screen.slamArea(0, CONTROLS_Y + idx - 2, SHERLOCK_SCREEN_WIDTH, + screen.slamArea(0, CONTROLS_Y + idx - 2, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y - idx + 2); events.delay(10); } @@ -2162,7 +2162,7 @@ void UserInterface::checkUseAction(const UseType *use, const Common::String &inv _infoFlag = true; clearInfo(); _infoFlag = true; - + // Display error message _menuCounter = 30; screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "You can't do that to yourself."); @@ -2191,7 +2191,7 @@ void UserInterface::checkUseAction(const UseType *use, const Common::String &inv if (targetNum != -1) { // Found a target, so do the action const UseType &action = use[targetNum]; - + events.setCursor(WAIT); if (action._useFlag) @@ -2274,7 +2274,7 @@ void UserInterface::checkAction(ActionType &action, const char *const messages[] cAnimNum = 9; else cAnimNum = action._cAnimNum - 1; - + int dir = -1; if (action._cAnimNum != 99) { CAnim &anim = scene._cAnim[cAnimNum]; @@ -2299,7 +2299,7 @@ void UserInterface::checkAction(ActionType &action, const char *const messages[] bool printed = false; for (int nameIdx = 0; nameIdx < 4; ++nameIdx) { - if (action._names[nameIdx].hasPrefix("*") && action._names[nameIdx].size() >= 2 + if (action._names[nameIdx].hasPrefix("*") && action._names[nameIdx].size() >= 2 && toupper(action._names[nameIdx][1]) == 'W') { if (obj.checkNameForCodes(Common::String(action._names[nameIdx].c_str() + 2), messages)) { if (!talk._talkToAbort) @@ -2367,7 +2367,7 @@ void UserInterface::checkAction(ActionType &action, const char *const messages[] screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "Done..."); // Set how long to show the message - _menuCounter = 30; + _menuCounter = 30; } } } -- cgit v1.2.3 From 44f3ae5005a8bc79ecb8f0670e466904fc375d31 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 7 May 2015 21:01:33 -0400 Subject: SHERLOCK: Fix pink dot appearing in lower-left corner of some player frames --- engines/sherlock/graphics.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index 132d3fa089..5dafb4cc76 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -143,7 +143,7 @@ void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &p const int TRANSPARENCY = 0xFF; for (int yp = 0; yp < drawRect.height(); ++yp) { const byte *srcP = (const byte *)src.getBasePtr( - flipped ? drawRect.right : drawRect.left, drawRect.top + yp); + flipped ? drawRect.right - 1 : drawRect.left, drawRect.top + yp); byte *destP = (byte *)getBasePtr(destPt.x, destPt.y + yp); for (int xp = 0; xp < drawRect.width(); ++xp, ++destP) { -- cgit v1.2.3 From 01ed05f295b878758ecf24c02480b2be153a8cf7 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Fri, 8 May 2015 06:56:09 +0200 Subject: SHERLOCK: Remove extra semi-column, some code formatting --- engines/sherlock/inventory.h | 2 +- engines/sherlock/people.cpp | 29 ++++++++++++++++++----------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index 0dafdddde9..68b88bd978 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -50,7 +50,7 @@ enum InvMode { struct InventoryItem { int _requiredFlag; Common::String _name; - Common::String _description;; + Common::String _description; Common::String _examine; int _lookFlag; diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index ee5f3bcb80..0a3ef693a8 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -397,14 +397,13 @@ void People::setWalking() { // If we're on the overhead map, set the sequence so we keep moving // in the same direction - if (map._active) { + if (map._active) _player._sequenceNumber = (oldDirection == -1) ? MAP_RIGHT : oldDirection; - } // Set the delta x _player._delta.x = (delta.x * 100) / (delta.y / speed.y); if (_walkDest.x < (_player._position.x / 100)) - _player._delta.x = -_player._delta.x;; + _player._delta.x = -_player._delta.x; _player._walkCount = delta.y / speed.y; } @@ -439,23 +438,31 @@ void People::gotoStand(Sprite &sprite) { switch (sprite._sequenceNumber) { case WALK_UP: - sprite._sequenceNumber = STOP_UP; break; + sprite._sequenceNumber = STOP_UP; + break; case WALK_DOWN: - sprite._sequenceNumber = STOP_DOWN; break; + sprite._sequenceNumber = STOP_DOWN; + break; case TALK_LEFT: case WALK_LEFT: - sprite._sequenceNumber = STOP_LEFT; break; + sprite._sequenceNumber = STOP_LEFT; + break; case TALK_RIGHT: case WALK_RIGHT: - sprite._sequenceNumber = STOP_RIGHT; break; + sprite._sequenceNumber = STOP_RIGHT; + break; case WALK_UPRIGHT: - sprite._sequenceNumber = STOP_UPRIGHT; break; + sprite._sequenceNumber = STOP_UPRIGHT; + break; case WALK_UPLEFT: - sprite._sequenceNumber = STOP_UPLEFT; break; + sprite._sequenceNumber = STOP_UPLEFT; + break; case WALK_DOWNRIGHT: - sprite._sequenceNumber = STOP_DOWNRIGHT; break; + sprite._sequenceNumber = STOP_DOWNRIGHT; + break; case WALK_DOWNLEFT: - sprite._sequenceNumber = STOP_DOWNLEFT; break; + sprite._sequenceNumber = STOP_DOWNLEFT; + break; default: break; } -- cgit v1.2.3 From 9114ca839d0ed46a8bb7123be950343a9ba36c4e Mon Sep 17 00:00:00 2001 From: Strangerke Date: Fri, 8 May 2015 07:08:46 +0200 Subject: SHERLOCK: Fix the definition of Surface's destructor --- engines/sherlock/graphics.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index 80b692130c..8e1bd438ea 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -41,7 +41,7 @@ protected: public: Surface(uint16 width, uint16 height); Surface(); - ~Surface(); + virtual ~Surface(); void create(uint16 width, uint16 height); void blitFrom(const Graphics::Surface &src); -- cgit v1.2.3 From 8b7ebf4269adda0dbd33e559ab5e3de047411f82 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Fri, 8 May 2015 07:15:40 +0200 Subject: SHERLOCK: Fix some compilation warnings using GCC --- engines/sherlock/map.h | 2 +- engines/sherlock/people.h | 3 ++- engines/sherlock/screen.h | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/map.h b/engines/sherlock/map.h index e4c6655db9..b4e92c600f 100644 --- a/engines/sherlock/map.h +++ b/engines/sherlock/map.h @@ -41,7 +41,7 @@ struct MapEntry : Common::Point { MapEntry() : Common::Point(), _translate(-1) {} - MapEntry(int x, int y, int translate) : Common::Point(x, y), _translate(translate) {} + MapEntry(int posX, int posY, int translate) : Common::Point(posX, posY), _translate(translate) {} }; class MapPaths { diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index 01ecd1a09a..02bb8dc950 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -45,8 +45,9 @@ enum { STOP_DOWN = 5, STOP_RIGHT = 6, STOP_UP = 7, WALK_UPRIGHT = 8, WALK_DOWNRIGHT = 9, WALK_UPLEFT = 10, WALK_DOWNLEFT = 11, STOP_UPRIGHT = 12, STOP_UPLEFT = 13, STOP_DOWNRIGHT = 14, - STOP_DOWNLEFT = 15, TALK_RIGHT = 6, TALK_LEFT = 4, + STOP_DOWNLEFT = 15, TALK_RIGHT = 6, TALK_LEFT = 4 }; + enum { MAP_UP = 1, MAP_UPRIGHT = 2, MAP_RIGHT = 1, MAP_DOWNRIGHT = 4, MAP_DOWN = 5, MAP_DOWNLEFT = 6, MAP_LEFT = 2, MAP_UPLEFT = 8 diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index bbfba1c575..b57f535983 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -82,7 +82,7 @@ public: byte _sMap[PALETTE_SIZE]; public: Screen(SherlockEngine *vm); - ~Screen(); + virtual ~Screen(); void setFont(int fontNumber); -- cgit v1.2.3 From fc5a0deb8915bb5bfc85626751539920752b386b Mon Sep 17 00:00:00 2001 From: Strangerke Date: Fri, 8 May 2015 17:54:53 +0200 Subject: SHERLOCK: Fix some more GCC warnings --- engines/sherlock/journal.cpp | 2 +- engines/sherlock/objects.cpp | 7 +++++-- engines/sherlock/people.cpp | 6 +++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 26aaa7a1a0..0c8864c302 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -1125,7 +1125,7 @@ int Journal::getFindName(bool printError) { if (events.kbHit()) { Common::KeyState keyState = events.getKey(); - if (keyState.keycode == Common::KEYCODE_BACKSPACE && name.c_str() > 0) { + if ((keyState.keycode == Common::KEYCODE_BACKSPACE) && (name.c_str() > 0)) { screen.vgaBar(Common::Rect(xp - screen.charWidth(name.lastChar()), yp, xp + 8, yp + 9), BUTTON_MIDDLE); xp -= screen.charWidth(name.lastChar()); screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), INV_FOREGROUND); diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 40c8b954cb..488d1fcf83 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -242,8 +242,8 @@ void Sprite::checkSprite() { // Invert percentage palPercent = 100 - palPercent; - for (int idx = palStart; idx < (palStart + palLength); ++idx) - screen._sMap[idx] = screen._cMap[idx] * palPercent / 100; + for (int i = palStart; i < (palStart + palLength); ++i) + screen._sMap[i] = screen._cMap[i] * palPercent / 100; events.pollEvents(); screen.setPalette(screen._sMap); @@ -352,6 +352,9 @@ void Sprite::checkSprite() { case DELTA: _position.x += 200; break; + + default: + break; } } } diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 0a3ef693a8..acc660b0c0 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -333,12 +333,12 @@ void People::setWalking() { // See whether the major movement is horizontal or vertical if (delta.x >= delta.y) { // Set the initial frame sequence for the left and right, as well - // as settting the delta x depending on direction + // as setting the delta x depending on direction if (_walkDest.x < (_player._position.x / 100)) { - _player._sequenceNumber = map._active ? MAP_LEFT : WALK_LEFT; + _player._sequenceNumber = (int) (map._active ? MAP_LEFT : WALK_LEFT); _player._delta.x = speed.x * -100; } else { - _player._sequenceNumber = map._active ? MAP_RIGHT : WALK_RIGHT; + _player._sequenceNumber = (int) (map._active ? MAP_RIGHT : WALK_RIGHT); _player._delta.x = speed.x * 100; } -- cgit v1.2.3 From d34e5d1a5975e9fd525dfec8b9460cfa026378d4 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Fri, 8 May 2015 18:01:51 +0200 Subject: SHERLOCK: Fix some more warnings --- engines/sherlock/scene.cpp | 3 ++- engines/sherlock/screen.cpp | 18 +++++++++--------- engines/sherlock/screen.h | 4 ++-- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index c1a73fee90..88f8674913 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -1414,7 +1414,8 @@ void Scene::doBgAnim() { // since we needed to finish the 'doBgAnim' to finish clearing the portrait if (people._clearingThePortrait && talk._scriptMoreFlag == 3) { // Reset the flags and call to talk - people._clearingThePortrait = talk._scriptMoreFlag = 0; + people._clearingThePortrait = false; + talk._scriptMoreFlag = 0; talk.talkTo(talk._scriptName); } } diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 72045a83fb..5623224b97 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -52,9 +52,9 @@ Screen::~Screen() { /** * Set the font to use for writing text on the screen */ -void Screen::setFont(int fontNumber) { - _fontNumber = fontNumber; - Common::String fname = Common::String::format("FONT%d.VGS", fontNumber + 1); +void Screen::setFont(int fontNumb) { + _fontNumber = fontNumb; + Common::String fname = Common::String::format("FONT%d.VGS", fontNumb + 1); // Discard any previous font and read in new one delete _font; @@ -278,8 +278,8 @@ void Screen::restoreBackground(const Common::Rect &r) { /** * Copies a given area to the screen */ -void Screen::slamArea(int16 xp, int16 yp, int16 w, int16 h) { - slamRect(Common::Rect(xp, yp, xp + w, yp + h)); +void Screen::slamArea(int16 xp, int16 yp, int16 width, int16 height) { + slamRect(Common::Rect(xp, yp, xp + width, yp + height)); } /** @@ -300,10 +300,10 @@ void Screen::slamRect(const Common::Rect &r) { * new area covered by the shape as well as the old area, which must be restored */ void Screen::flushImage(ImageFrame *frame, const Common::Point &pt, - int16 *xp, int16 *yp, int16 *w, int16 *h) { + int16 *xp, int16 *yp, int16 *width, int16 *height) { Common::Point imgPos = pt + frame->_offset; Common::Rect newBounds(imgPos.x, imgPos.y, imgPos.x + frame->_frame.w, imgPos.y + frame->_frame.h); - Common::Rect oldBounds(*xp, *yp, *xp + *w, *yp + *h); + Common::Rect oldBounds(*xp, *yp, *xp + *width, *yp + *height); // See if the areas of the old and new overlap, and if so combine the areas if (newBounds.intersects(oldBounds)) { @@ -321,8 +321,8 @@ void Screen::flushImage(ImageFrame *frame, const Common::Point &pt, *xp = newBounds.left; *yp = newBounds.top; - *w = newBounds.width(); - *h = newBounds.height(); + *width = newBounds.width(); + *height = newBounds.height(); } /** diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index b57f535983..13a4549161 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -107,11 +107,11 @@ public: void restoreBackground(const Common::Rect &r); - void slamArea(int16 xp, int16 yp, int16 w, int16 h); + void slamArea(int16 xp, int16 yp, int16 width, int16 height); void slamRect(const Common::Rect &r); void flushImage(ImageFrame *frame, const Common::Point &pt, - int16 *xp, int16 *yp, int16 *w, int16 *h); + int16 *xp, int16 *yp, int16 *width, int16 *height); int stringWidth(const Common::String &str); -- cgit v1.2.3 From bf0882badc0f29aa8df687fb6f2d0fddded209ab Mon Sep 17 00:00:00 2001 From: Strangerke Date: Fri, 8 May 2015 18:28:45 +0200 Subject: SHERLOCK: Fix some more GCC warnings --- engines/sherlock/screen.cpp | 18 +++++++++--------- engines/sherlock/screen.h | 4 ++-- engines/sherlock/talk.cpp | 16 ++++++++-------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 5623224b97..e22c4daad7 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -329,13 +329,13 @@ void Screen::flushImage(ImageFrame *frame, const Common::Point &pt, * Prints the text passed onto the back buffer at the given position and color. * The string is then blitted to the screen */ -void Screen::print(const Common::Point &pt, byte color, const char *format, ...) { +void Screen::print(const Common::Point &pt, byte color, const char *formatStr, ...) { // Create the string to display char buffer[100]; va_list args; - va_start(args, format); - vsprintf(buffer, format, args); + va_start(args, formatStr); + vsprintf(buffer, formatStr, args); va_end(args); Common::String str(buffer); @@ -363,13 +363,13 @@ void Screen::print(const Common::Point &pt, byte color, const char *format, ...) /** * Print a strings onto the back buffer without blitting it to the screen */ -void Screen::gPrint(const Common::Point &pt, byte color, const char *format, ...) { +void Screen::gPrint(const Common::Point &pt, byte color, const char *formatStr, ...) { // Create the string to display char buffer[100]; va_list args; - va_start(args, format); - vsprintf(buffer, format, args); + va_start(args, formatStr); + vsprintf(buffer, formatStr, args); va_end(args); Common::String str(buffer); @@ -519,10 +519,10 @@ Common::Rect Screen::getDisplayBounds() { * Synchronize the data for a savegame */ void Screen::synchronize(Common::Serializer &s) { - int fontNumber = _fontNumber; - s.syncAsByte(fontNumber); + int fontNumb = _fontNumber; + s.syncAsByte(fontNumb); if (s.isLoading()) - setFont(fontNumber); + setFont(fontNumb); } } // End of namespace Sherlock diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 13a4549161..7e33a12b7b 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -102,8 +102,8 @@ public: void verticalTransition(); - void print(const Common::Point &pt, byte color, const char *format, ...); - void gPrint(const Common::Point &pt, byte color, const char *format, ...); + void print(const Common::Point &pt, byte color, const char *formatStr, ...); + void gPrint(const Common::Point &pt, byte color, const char *formatStr, ...); void restoreBackground(const Common::Rect &r); diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 55a79f8170..6d56149c6c 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -604,7 +604,7 @@ void Talk::stripVoiceCommands() { // Scan for an sound effect byte, which indicates to play a sound for (uint idx = 0; idx < statement._reply.size(); ++idx) { - if (statement._reply[idx] == SFX_COMMAND) { + if (statement._reply[idx] == (int)SFX_COMMAND) { // Replace instruction character with a space, and delete the // rest of the name following it statement._reply = Common::String(statement._reply.c_str(), @@ -1391,11 +1391,11 @@ void Talk::doScript(const Common::String &script) { str += str[0] & 127; for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) { - Object &obj = scene._bgShapes[idx]; - if (scumm_stricmp(tempString.c_str(), obj._name.c_str()) == 0) { + Object &object = scene._bgShapes[idx]; + if (scumm_stricmp(tempString.c_str(), object._name.c_str()) == 0) { // Only toggle the object if it's not in the desired state already - if ((obj._type == HIDDEN && state) || (obj._type != HIDDEN && !state)) - obj.toggleHidden(); + if ((object._type == HIDDEN && state) || (object._type != HIDDEN && !state)) + object.toggleHidden(); } } break; @@ -1460,13 +1460,13 @@ void Talk::doScript(const Common::String &script) { case WALK_TO_CANIMATION: { ++str; - CAnim &anim = scene._cAnim[str[0] - 1]; + CAnim &animation = scene._cAnim[str[0] - 1]; - // Save the current point in the script, since it might be intterupted by + // Save the current point in the script, since it might be interrupted by // doing bg anims in the next call, so we need to know where to return to _scriptCurrentIndex = (str + 1) - scriptStart; - people.walkToCoords(anim._goto, anim._gotoDir); + people.walkToCoords(animation._goto, animation._gotoDir); if (_talkToAbort) return; break; -- cgit v1.2.3 From 263f33a9f83f9d1d00a100b7532dd28e59ee3a6b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 8 May 2015 20:41:12 -0400 Subject: SHERLOCK: Fix some reads beyond script end in doScript --- engines/sherlock/talk.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 6d56149c6c..bbc61a3c13 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1010,6 +1010,7 @@ void Talk::doScript(const Common::String &script) { _savedSequences.clear(); const byte *scriptStart = (const byte *)script.c_str(); + const byte *scriptEnd = scriptStart + script.size(); const byte *str = scriptStart; if (_scriptMoreFlag) { @@ -1577,13 +1578,13 @@ void Talk::doScript(const Common::String &script) { ++line; // Certain different conditions require a wait - if ((line == 4 && str[0] != SFX_COMMAND && str[0] != PAUSE && _speaker != -1) || - (line == 5 && str[0] != PAUSE && _speaker == -1) || + if ((line == 4 && str < scriptEnd && str[0] != SFX_COMMAND && str[0] != PAUSE && _speaker != -1) || + (line == 5 && str < scriptEnd && str[0] != PAUSE && _speaker == -1) || endStr) { wait = 1; } - switch (str[0]) { + switch (str >= scriptEnd ? 0 : str[0]) { case SWITCH_SPEAKER: case ASSIGN_PORTRAIT_LOCATION: case BANISH_WINDOW: @@ -1631,7 +1632,7 @@ void Talk::doScript(const Common::String &script) { } // Clear the window unless the wait was due to a PAUSE command - if (!pauseFlag && wait != -1 && str[0] != SFX_COMMAND) { + if (!pauseFlag && wait != -1 && str < scriptEnd && str[0] != SFX_COMMAND) { if (!_talkStealth) ui.clearWindow(); yp = CONTROLS_Y + 12; -- cgit v1.2.3 From 7ca37bef9f6b16f175f39908c8dfbb1761d42aa3 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 8 May 2015 22:54:32 -0400 Subject: SHERLOCK: Simplify detection entry --- engines/sherlock/detection.cpp | 8 -------- engines/sherlock/detection_tables.h | 8 ++------ engines/sherlock/sherlock.h | 1 - 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp index 734db007ba..aae8b0ad0e 100644 --- a/engines/sherlock/detection.cpp +++ b/engines/sherlock/detection.cpp @@ -33,7 +33,6 @@ struct SherlockGameDescription { ADGameDescription desc; int gameID; - uint32 features; }; /** @@ -43,13 +42,6 @@ uint32 SherlockEngine::getGameID() const { return _gameDescription->gameID; } -/** - * Returns the features the currently playing game has - */ -uint32 SherlockEngine::getGameFeatures() const { - return _gameDescription->features; -} - /** * Return's the platform the game's datafiles are for */ diff --git a/engines/sherlock/detection_tables.h b/engines/sherlock/detection_tables.h index 1d7326058e..401ede3b07 100644 --- a/engines/sherlock/detection_tables.h +++ b/engines/sherlock/detection_tables.h @@ -28,20 +28,16 @@ static const SherlockGameDescription gameDescriptions[] = { { "scalpel", 0, - { - { "talk.lib", 0, "ad0c4d6865edf15da4e9204c08815875", 238928 }, - AD_LISTEND - }, + AD_ENTRY1s("talk.lib", "ad0c4d6865edf15da4e9204c08815875", 238928), Common::EN_ANY, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO1(GUIO_NOSPEECH) }, GType_SerratedScalpel, - 0 }, - { AD_TABLE_END_MARKER, 0, 0 } + { AD_TABLE_END_MARKER } }; } // End of namespace MADS diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 06d38cbf89..79a3c11135 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -122,7 +122,6 @@ public: int getGameType() const; uint32 getGameID() const; - uint32 getGameFeatures() const; Common::Language getLanguage() const; Common::Platform getPlatform() const; -- cgit v1.2.3 From 4c7e840388afb4c573d9740614b75883688c55ec Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 8 May 2015 23:05:27 -0400 Subject: SHERLOCK: Fix meta engine initialization --- engines/sherlock/detection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp index aae8b0ad0e..dd02bd7694 100644 --- a/engines/sherlock/detection.cpp +++ b/engines/sherlock/detection.cpp @@ -62,7 +62,7 @@ static const PlainGameDescriptor sherlockGames[] = { class SherlockMetaEngine : public AdvancedMetaEngine { public: - SherlockMetaEngine() : AdvancedMetaEngine(Sherlock::gameDescriptions, sizeof(Sherlock::gameDescriptions), sherlockGames) {} + SherlockMetaEngine() : AdvancedMetaEngine(Sherlock::gameDescriptions, sizeof(Sherlock::SherlockGameDescription), sherlockGames) {} virtual const char *getName() const { return "Sherlock Engine"; -- cgit v1.2.3 From 8d89bf9bc6c067af4deaf86d4ae8c3430d584851 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Sat, 9 May 2015 09:42:16 +0200 Subject: SHERLOCK: Fix some more GCC warnings --- engines/sherlock/journal.cpp | 4 ++-- engines/sherlock/resources.cpp | 14 +++++++------- engines/sherlock/scalpel/scalpel.cpp | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 0c8864c302..5ecb5ae26c 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -290,10 +290,10 @@ int Journal::loadJournalFile(bool alreadyLoaded) { journalString += NAMES[talk._talkTo]; const byte *strP = replyP + 1; - char v; + byte v; do { v = *strP++; - } while (v && v < 128 && v != '.' && v != '!' && v != '?'); + } while (v && (v < 128) && (v != '.') && (v != '!') && (v != '?')); if (v == '?') journalString += " asked, \""; diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index 715ca492ae..c64f4e4923 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -343,9 +343,9 @@ void ImageFile::loadPalette(Common::SeekableReadStream &stream) { int v2 = stream.readUint16LE() + 1; stream.skip(1); // Skip paletteBase byte bool rleEncoded = stream.readByte() == 1; - int size = v1 * v2; + int palSize = v1 * v2; - if ((size - 12) == PALETTE_SIZE && !rleEncoded) { + if ((palSize - 12) == PALETTE_SIZE && !rleEncoded) { // Found palette, so read it in stream.seek(2 + 12, SEEK_CUR); for (int idx = 0; idx < PALETTE_SIZE; ++idx) @@ -373,21 +373,21 @@ void ImageFile::decompressFrame(ImageFrame &frame, const byte *src) { // RLE encoded byte *dst = (byte *)frame._frame.getPixels(); - int size = frame._width * frame._height; - while (size > 0) { + int frameSize = frame._width * frame._height; + while (frameSize > 0) { if (*src == frame._rleMarker) { byte rleColor = src[1]; byte rleCount = src[2]; src += 3; - size -= rleCount; + frameSize -= rleCount; while (rleCount--) *dst++ = rleColor; } else { *dst++ = *src++; - --size; + --frameSize; } } - assert(size == 0); + assert(frameSize == 0); } else { // Uncompressed frame Common::copy(src, src + frame._width * frame._height, diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 6ba6b33340..4cd613d48f 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -485,7 +485,7 @@ void ScalpelEngine::loadInventory() { inv.push_back(InventoryItem(544, "Tarot", "Tarot Cards", "_ITEM71A")); inv.push_back(InventoryItem(544, "Ornate Key", "An ornate key", "_ITEM70A")); inv.push_back(InventoryItem(586, "Pawn ticket", "A pawn ticket", "_ITEM16A")); -}; +} /** * Transition to show an image -- cgit v1.2.3 From e3e4354f880d5f9354706b8f20d204960c48bb97 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Sat, 9 May 2015 10:21:46 +0200 Subject: SHERLOCK: Remove the use of ++ on boolean variables --- engines/sherlock/objects.cpp | 8 ++++---- engines/sherlock/user_interface.cpp | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 488d1fcf83..35b270dd13 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -909,13 +909,13 @@ int Object::checkNameForCodes(const Common::String &name, const char *const mess } else if (name.hasPrefix("!")) { // Message attached to canimation int messageNum = atoi(name.c_str() + 1); - ui._infoFlag++; + ui._infoFlag = true; ui.clearInfo(); screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, messages[messageNum]); ui._menuCounter = 25; } else if (name.hasPrefix("@")) { // Message attached to canimation - ui._infoFlag++; + ui._infoFlag = true; ui.clearInfo(); screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, name.c_str() + 1); printed = true; @@ -1010,7 +1010,7 @@ int Object::pickUpObject(const char *const messages[]) { if (message > 50) message -= 50; - ++ui._infoFlag; + ui._infoFlag = true; ui.clearInfo(); screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, messages[message]); ui._menuCounter = 30; @@ -1056,7 +1056,7 @@ int Object::pickUpObject(const char *const messages[]) { numObjects = inv.putItemInInventory(*this); if (!printed) { - ui._infoFlag++; + ui._infoFlag = true; ui.clearInfo(); Common::String itemName = _description; diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index f048e280a8..ce282aa2c2 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -428,7 +428,7 @@ void UserInterface::restoreButton(int num) { screen.slamArea(pt.x, pt.y, pt.x + frame.w, pt.y + frame.h); if (!_menuCounter) { - _infoFlag++; + _infoFlag = true; clearInfo(); } } @@ -515,7 +515,7 @@ void UserInterface::clearWindow() { void UserInterface::whileMenuCounter() { if (!(--_menuCounter) || _vm->_events->checkInput()) { _menuCounter = 0; - ++_infoFlag; + _infoFlag = true; clearInfo(); } } @@ -1259,7 +1259,7 @@ void UserInterface::doLookControl() { Screen &screen = *_vm->_screen; _key = _oldKey = -1; - _keyboardInput = _keycode != Common::KEYCODE_INVALID; + _keyboardInput = (_keycode != Common::KEYCODE_INVALID); if (events._released || events._rightReleased || _keyboardInput) { // Is an inventory object being looked at? @@ -1360,7 +1360,7 @@ void UserInterface::doMainControl() { // Check if the button being pointed to has changed if (_oldKey != _key && !_windowOpen) { // Clear the info line - _infoFlag++; + _infoFlag = true; clearInfo(); // If there was an old button selected, restore it @@ -2215,7 +2215,7 @@ void UserInterface::checkUseAction(const UseType *use, const Common::String &inv // Print "Done..." as an ending, unless flagged for leaving scene or otherwise flagged if (scene._goToScene != 1 && !printed && !talk._talkToAbort) { - _infoFlag++; + _infoFlag = true; clearInfo(); screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "Done..."); _menuCounter = 25; -- cgit v1.2.3 From f622d7471e7f04f92c728cab7de9dd0a109886c3 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Sat, 9 May 2015 13:08:36 +0200 Subject: SHERLOCK: Some more fixes --- engines/sherlock/journal.cpp | 2 +- engines/sherlock/people.cpp | 4 ++-- engines/sherlock/talk.cpp | 33 +++++++++++++++++---------------- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 5ecb5ae26c..926ccee38a 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -1125,7 +1125,7 @@ int Journal::getFindName(bool printError) { if (events.kbHit()) { Common::KeyState keyState = events.getKey(); - if ((keyState.keycode == Common::KEYCODE_BACKSPACE) && (name.c_str() > 0)) { + if ((keyState.keycode == Common::KEYCODE_BACKSPACE) && (name.size() > 0)) { screen.vgaBar(Common::Rect(xp - screen.charWidth(name.lastChar()), yp, xp + 8, yp + 9), BUTTON_MIDDLE); xp -= screen.charWidth(name.lastChar()); screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), INV_FOREGROUND); diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index acc660b0c0..f73ebd8cb0 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -335,10 +335,10 @@ void People::setWalking() { // Set the initial frame sequence for the left and right, as well // as setting the delta x depending on direction if (_walkDest.x < (_player._position.x / 100)) { - _player._sequenceNumber = (int) (map._active ? MAP_LEFT : WALK_LEFT); + _player._sequenceNumber = (map._active ? (int)MAP_LEFT : (int)WALK_LEFT); _player._delta.x = speed.x * -100; } else { - _player._sequenceNumber = (int) (map._active ? MAP_RIGHT : WALK_RIGHT); + _player._sequenceNumber = (map._active ? (int)MAP_RIGHT : (int)WALK_RIGHT); _player._delta.x = speed.x * 100; } diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index bbc61a3c13..74bd98c4e1 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -604,7 +604,7 @@ void Talk::stripVoiceCommands() { // Scan for an sound effect byte, which indicates to play a sound for (uint idx = 0; idx < statement._reply.size(); ++idx) { - if (statement._reply[idx] == (int)SFX_COMMAND) { + if (statement._reply[idx] == (char)SFX_COMMAND) { // Replace instruction character with a space, and delete the // rest of the name following it statement._reply = Common::String(statement._reply.c_str(), @@ -1004,7 +1004,6 @@ void Talk::doScript(const Common::String &script) { int line = 0; bool noTextYet = true; bool openTalkWindow = false; - int obj; int seqCount; _savedSequences.clear(); @@ -1164,18 +1163,19 @@ void Talk::doScript(const Common::String &script) { break; case ADJUST_OBJ_SEQUENCE: + { // Get the name of the object to adjust ++str; for (int idx = 0; idx < (str[0] & 127); ++idx) tempString += str[idx + 2]; // Scan for object - obj = -1; + int objId = -1; for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) { if (scumm_stricmp(tempString.c_str(), scene._bgShapes[idx]._name.c_str()) == 0) - obj = idx; + objId = idx; } - if (obj == -1) + if (objId == -1) error("Could not find object %s to change", tempString.c_str()); // Should the script be overwritten? @@ -1183,10 +1183,10 @@ void Talk::doScript(const Common::String &script) { // Save the current sequence _savedSequences.push(SequenceEntry()); SequenceEntry &seqEntry = _savedSequences.top(); - seqEntry._objNum = obj; - seqEntry._seqTo = scene._bgShapes[obj]._seqTo; - for (uint idx = 0; idx < scene._bgShapes[obj]._seqSize; ++idx) - seqEntry._sequences.push_back(scene._bgShapes[obj]._sequences[idx]); + seqEntry._objNum = objId; + seqEntry._seqTo = scene._bgShapes[objId]._seqTo; + for (uint idx = 0; idx < scene._bgShapes[objId]._seqSize; ++idx) + seqEntry._sequences.push_back(scene._bgShapes[objId]._sequences[idx]); } // Get number of bytes to change @@ -1195,14 +1195,15 @@ void Talk::doScript(const Common::String &script) { // Copy in the new sequence for (int idx = 0; idx < seqCount; ++idx, ++str) - scene._bgShapes[obj]._sequences[idx] = str[0] - 1; + scene._bgShapes[objId]._sequences[idx] = str[0] - 1; // Reset object back to beginning of new sequence - scene._bgShapes[obj]._frameNumber = 0; + scene._bgShapes[objId]._frameNumber = 0; continue; + } case WALK_TO_COORDS: - // Save the current point in the script, since it might be intterupted by + // Save the current point in the script, since it might be interrupted by // doing bg anims in the next call, so we need to know where to return to ++str; _scriptCurrentIndex = str - scriptStart; @@ -1646,12 +1647,12 @@ void Talk::doScript(const Common::String &script) { if (wait != -1) { for (int ssIndex = 0; ssIndex < (int)_savedSequences.size(); ++ssIndex) { SequenceEntry &seq = _savedSequences[ssIndex]; - Object &obj = scene._bgShapes[seq._objNum]; + Object &object = scene._bgShapes[seq._objNum]; for (uint idx = 0; idx < seq._sequences.size(); ++idx) - obj._sequences[idx] = seq._sequences[idx]; - obj._frameNumber = seq._frameNumber; - obj._seqTo = seq._seqTo; + object._sequences[idx] = seq._sequences[idx]; + object._frameNumber = seq._frameNumber; + object._seqTo = seq._seqTo; } pullSequence(); -- cgit v1.2.3 From 13c06c100e6eac2538de3ec178e654147c38bb1f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 08:41:13 -0400 Subject: SHERLOCK: Simplify animation loading filename handling --- engines/sherlock/animation.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index fc84680d5e..46568f8742 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -78,13 +78,8 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade, // Check for any any sound frames for the given animation const int *soundFrames = checkForSoundFrames(filename); - // Strip any extension off of the passed filename and add .vdx suffix - Common::String baseName = filename; - const char *p = strchr(baseName.c_str(), '.'); - if (p) - baseName = Common::String(filename.c_str(), MIN(p - 1, baseName.c_str() + 7)); - - Common::String vdxName = baseName + ".vdx"; + // Add on the VDX extension + Common::String vdxName = filename + ".vdx"; // Load the animation Common::SeekableReadStream *stream; @@ -96,7 +91,7 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade, stream = _vm->_res->load(vdxName, "epilogue.lib"); // Load initial image - Common::String vdaName = baseName + ".vda"; + Common::String vdaName = filename + ".vda"; ImageFile images(vdaName, true, true); events.wait(minDelay); @@ -144,8 +139,8 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade, ++soundNumber; ++soundFrames; Common::String fname = _vm->_soundOverride.empty() ? - Common::String::format("%s%01d", baseName.c_str(), soundNumber) : - Common::String::format("%s%02d", baseName.c_str(), soundNumber); + Common::String::format("%s%01d", filename.c_str(), soundNumber) : + Common::String::format("%s%02d", filename.c_str(), soundNumber); if (sound._voices) sound.playSound(fname); -- cgit v1.2.3 From 1ef5b667925d5813bde6aba2392e3cb19cb08f22 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 08:56:12 -0400 Subject: SHERLOCK: Cleanup fixes for animation player --- engines/sherlock/animation.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 46568f8742..ced03e8a49 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -127,7 +127,8 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade, // since we don't want the offsets in the image file to be used, just the explicit position we specify screen.transBlitFrom(images[imageFrame]._frame, pt); } else { - // No sprite to show for this animation frame + // At this point, either the sprites for the frame has been complete, or there weren't any sprites + // at all to draw for the frame if (fade == 255) { // Gradual fade in if (screen.equalizePalette(images._palette) == 0) @@ -178,14 +179,14 @@ const int *Animation::checkForSoundFrames(const Common::String &filename) { if (_vm->_soundOverride.empty()) { for (int idx = 0; idx < PROLOGUE_NAMES_COUNT; ++idx) { - if (!scumm_stricmp(filename.c_str(), PROLOGUE_NAMES[idx])) { + if (!filename.equalsIgnoreCase(PROLOGUE_NAMES[idx])) { frames = &PROLOGUE_FRAMES[idx][0]; break; } } } else { for (int idx = 0; idx < TITLE_NAMES_COUNT; ++idx) { - if (!scumm_stricmp(filename.c_str(), TITLE_NAMES[idx])) { + if (!filename.equalsIgnoreCase(TITLE_NAMES[idx])) { frames = &TITLE_FRAMES[idx][0]; break; } -- cgit v1.2.3 From 47bcb5358acddc3ef75f5a4af59ba43f06027490 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 09:09:10 -0400 Subject: SHERLOCK: Cleanup fix for decompress --- engines/sherlock/decompress.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/engines/sherlock/decompress.cpp b/engines/sherlock/decompress.cpp index b319bc90c8..7c98b50543 100644 --- a/engines/sherlock/decompress.cpp +++ b/engines/sherlock/decompress.cpp @@ -48,7 +48,7 @@ Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source, int lzWindowPos = 0xFEE; cmd = 0; - while (1) { + do { cmd >>= 1; if (!(cmd & 0x100)) cmd = source.readByte() | 0xFF00; @@ -72,9 +72,7 @@ Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source, int lzWindowPos = (lzWindowPos + 1) & 0x0FFF; } } - if (outBuffer >= outBufferEnd) - break; - } + } while (outBuffer < outBufferEnd); return outS; } -- cgit v1.2.3 From 5d41f0f9aa5d4df586949362fcedec447d1d6094 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 09:17:30 -0400 Subject: SHERLOCK: Give the GTYPE constants an explicit enum type --- engines/sherlock/detection.cpp | 6 +++--- engines/sherlock/sherlock.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp index dd02bd7694..82ac5a4c3d 100644 --- a/engines/sherlock/detection.cpp +++ b/engines/sherlock/detection.cpp @@ -32,18 +32,18 @@ namespace Sherlock { struct SherlockGameDescription { ADGameDescription desc; - int gameID; + GameType gameID; }; /** * Returns the Id of the game */ -uint32 SherlockEngine::getGameID() const { +GameType SherlockEngine::getGameID() const { return _gameDescription->gameID; } /** - * Return's the platform the game's datafiles are for + * Returns the platform the game's datafiles are for */ Common::Platform SherlockEngine::getPlatform() const { return _gameDescription->desc.platform; diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 79a3c11135..a516e52ae7 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -57,7 +57,7 @@ enum { kDebugScript = 1 << 0 }; -enum { +enum GameType { GType_SerratedScalpel = 0, GType_RoseTattoo = 1 }; @@ -121,7 +121,7 @@ public: virtual void syncSoundSettings(); int getGameType() const; - uint32 getGameID() const; + GameType getGameID() const; Common::Language getLanguage() const; Common::Platform getPlatform() const; -- cgit v1.2.3 From 4950deaf33dc46521e495d36b9d0f1933d007aa1 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 09:24:22 -0400 Subject: SHERLOCK: Cleanup for Debugger class --- engines/sherlock/debugger.cpp | 6 +++--- engines/sherlock/debugger.h | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/engines/sherlock/debugger.cpp b/engines/sherlock/debugger.cpp index b3dac71d5e..ff9a8056b0 100644 --- a/engines/sherlock/debugger.cpp +++ b/engines/sherlock/debugger.cpp @@ -27,13 +27,13 @@ namespace Sherlock { Debugger::Debugger(SherlockEngine *vm) : GUI::Debugger(), _vm(vm) { registerCmd("continue", WRAP_METHOD(Debugger, cmdExit)); - registerCmd("scene", WRAP_METHOD(Debugger, cmd_scene)); + registerCmd("scene", WRAP_METHOD(Debugger, cmdScene)); } /** * Converts a decimal or hexadecimal string into a number */ -static int strToInt(const char *s) { +int Debugger::strToInt(const char *s) { if (!*s) // No string at all return 0; @@ -52,7 +52,7 @@ static int strToInt(const char *s) { /** * Switch to another scene */ -bool Debugger::cmd_scene(int argc, const char **argv) { +bool Debugger::cmdScene(int argc, const char **argv) { if (argc != 2) { debugPrintf("Format: scene \n"); return true; diff --git a/engines/sherlock/debugger.h b/engines/sherlock/debugger.h index 8c7291c9e6..fe77007975 100644 --- a/engines/sherlock/debugger.h +++ b/engines/sherlock/debugger.h @@ -33,8 +33,10 @@ class SherlockEngine; class Debugger : public GUI::Debugger { private: SherlockEngine *_vm; -protected: - bool cmd_scene(int argc, const char **argv); + + int strToInt(const char *s); + + bool cmdScene(int argc, const char **argv); public: Debugger(SherlockEngine *vm); virtual ~Debugger() {} -- cgit v1.2.3 From ccb8c03737ef04dc7ec964cba3516652def3d077 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 09:29:06 -0400 Subject: SHERLOCK: Further cleanup fixes for detection --- engines/sherlock/detection.cpp | 3 +-- engines/sherlock/detection_tables.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp index 82ac5a4c3d..a6b980fea3 100644 --- a/engines/sherlock/detection.cpp +++ b/engines/sherlock/detection.cpp @@ -52,7 +52,6 @@ Common::Platform SherlockEngine::getPlatform() const { } // End of namespace Sherlock static const PlainGameDescriptor sherlockGames[] = { - {"sherlock", "The Lost Files of Sherlock Holmes"}, { "scalpel", "The Case of the Serrated Scalpel" }, { "rosetattoo", "The Case of the Rose Tattoo" }, {0, 0} @@ -127,7 +126,7 @@ bool Sherlock::SherlockEngine::hasFeature(EngineFeature f) const { * Return a list of savegames */ SaveStateList SherlockMetaEngine::listSaves(const char *target) const { - return Sherlock::SaveManager(nullptr, "").getSavegameList(target); + return Sherlock::SaveManager::getSavegameList(target); } /** diff --git a/engines/sherlock/detection_tables.h b/engines/sherlock/detection_tables.h index 401ede3b07..8f17e8f8ea 100644 --- a/engines/sherlock/detection_tables.h +++ b/engines/sherlock/detection_tables.h @@ -37,7 +37,7 @@ static const SherlockGameDescription gameDescriptions[] = { GType_SerratedScalpel, }, - { AD_TABLE_END_MARKER } + { AD_TABLE_END_MARKER, (GameType)0 } }; } // End of namespace MADS -- cgit v1.2.3 From c85b14b402ef03757c0a5ab320d8c0ef6dba5483 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 10:01:36 -0400 Subject: SHERLOCK: More comment fixes --- engines/sherlock/detection_tables.h | 2 +- engines/sherlock/events.cpp | 2 +- engines/sherlock/objects.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/engines/sherlock/detection_tables.h b/engines/sherlock/detection_tables.h index 8f17e8f8ea..b369868741 100644 --- a/engines/sherlock/detection_tables.h +++ b/engines/sherlock/detection_tables.h @@ -40,4 +40,4 @@ static const SherlockGameDescription gameDescriptions[] = { { AD_TABLE_END_MARKER, (GameType)0 } }; -} // End of namespace MADS +} // End of namespace Sherlock diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index 4e3f81e588..1bc2e64f6e 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -296,4 +296,4 @@ bool Events::checkInput() { return kbHit() || _pressed || _released || _rightPressed || _rightReleased; } -} // End of namespace MADS +} // End of namespace Sherlock diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 861858c58e..f6ad6beb0d 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -145,7 +145,7 @@ enum { REVERSE_DIRECTION = 0x80 }; struct ActionType { int _cAnimNum; - int _cAnimSpeed; // if high bit set, play in reverse + int _cAnimSpeed; Common::String _names[4]; void synchronize(Common::SeekableReadStream &s); @@ -153,7 +153,7 @@ struct ActionType { struct UseType { int _cAnimNum; - int _cAnimSpeed; // if high bit set, play in reverse + int _cAnimSpeed; Common::String _names[4]; int _useFlag; // Which flag USE will set (if any) int _dFlag[1]; -- cgit v1.2.3 From 8306451462e6ffa91ac3bf76e30b43f3777dbd89 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Sat, 9 May 2015 16:14:39 +0200 Subject: SHERLOCK: Fix string equality tests --- engines/sherlock/animation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index ced03e8a49..299a8186d7 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -179,14 +179,14 @@ const int *Animation::checkForSoundFrames(const Common::String &filename) { if (_vm->_soundOverride.empty()) { for (int idx = 0; idx < PROLOGUE_NAMES_COUNT; ++idx) { - if (!filename.equalsIgnoreCase(PROLOGUE_NAMES[idx])) { + if (filename.equalsIgnoreCase(PROLOGUE_NAMES[idx])) { frames = &PROLOGUE_FRAMES[idx][0]; break; } } } else { for (int idx = 0; idx < TITLE_NAMES_COUNT; ++idx) { - if (!filename.equalsIgnoreCase(TITLE_NAMES[idx])) { + if (filename.equalsIgnoreCase(TITLE_NAMES[idx])) { frames = &TITLE_FRAMES[idx][0]; break; } -- cgit v1.2.3 From 00fb65c1dcfe97e0b5550bf805d87c736c5f19c6 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 10:32:45 -0400 Subject: SHERLOCK: Cleanup fixes for event manager --- engines/sherlock/events.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index 1bc2e64f6e..886306fc0e 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -188,9 +188,6 @@ bool Events::checkForNextFrameCounter() { // Display the frame _vm->_screen->update(); - // Signal the ScummVM debugger - _vm->_debugger->onFrame(); - return true; } @@ -267,7 +264,10 @@ bool Events::delay(uint32 time, bool interruptable) { } /** - * Sets the pressed and released button flags depending on the value passed + * Sets the pressed and released button flags on the raw button state previously set in pollEvents calls. + * @remarks The events manager has separate variables for the raw immediate and old button state + * versus the current buttons states for the frame. This method is expected to be called only once + * per game frame */ void Events::setButtonState() { _released = _rightReleased = false; -- cgit v1.2.3 From 5f71643cba4937367182d3c6751fcfecfbb09573 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 10:35:43 -0400 Subject: SHERLOCK: Remove Surface constructor no longer being used --- engines/sherlock/graphics.cpp | 8 -------- engines/sherlock/graphics.h | 2 -- 2 files changed, 10 deletions(-) diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index 5dafb4cc76..bdb4df6c83 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -31,14 +31,6 @@ Surface::Surface(uint16 width, uint16 height): _freePixels(true) { create(width, height); } -Surface::Surface(Surface &src, const Common::Rect &r) : _freePixels(false) { - setPixels(src.getBasePtr(r.left, r.top)); - w = r.width(); - h = r.height(); - pitch = src.pitch; - format = Graphics::PixelFormat::createFormatCLUT8(); -} - Surface::Surface() : _freePixels(false) { } diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index 8e1bd438ea..8ed508fad0 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -36,8 +36,6 @@ private: bool clip(Common::Rect &srcBounds, Common::Rect &destBounds); protected: virtual void addDirtyRect(const Common::Rect &r) {} - - Surface(Surface &src, const Common::Rect &r); public: Surface(uint16 width, uint16 height); Surface(); -- cgit v1.2.3 From 1518d14c3412fa6cf5aaf2bb3bbedfe61d37c15e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 11:25:05 -0400 Subject: SHERLOCK: Cleanup fixes for Inventory --- engines/sherlock/inventory.cpp | 8 +++++--- engines/sherlock/inventory.h | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index 99db461ea4..c3e2e14393 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -79,7 +79,9 @@ void Inventory::freeGraphics() { _invGraphicsLoaded = false; } -/** Load the list of names the inventory items correspond to. +/** + * Load the list of names the inventory items correspond to, if not already loaded, + * and then calls loadGraphics to load the associated graphics */ void Inventory::loadInv() { // Exit if the inventory names are already loaded @@ -88,9 +90,9 @@ void Inventory::loadInv() { // Load the inventory names Common::SeekableReadStream *stream = _vm->_res->load("invent.txt"); - _names.clear(); - while (stream->pos() < stream->size()) { + int streamSize = stream->size(); + while (stream->pos() < streamSize) { Common::String name; char c; while ((c = stream->readByte()) != 0) diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index 68b88bd978..bec26b333d 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -72,7 +72,8 @@ public: bool _invGraphicsLoaded; InvMode _invMode; int _invIndex; - int _holdings; + int _holdings; // Used to hold number of visible items in active inventory. + // Since Inventory array also contains some special hidden items void freeGraphics(); int _oldFlag; int _invFlag; -- cgit v1.2.3 From 902b79116552b0605668f130e0695e4798ef87d5 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Sat, 9 May 2015 18:04:13 +0200 Subject: SHERLOCK: Make copyright headers consistent --- engines/sherlock/animation.cpp | 4 ++-- engines/sherlock/animation.h | 4 ++-- engines/sherlock/debugger.cpp | 6 +++--- engines/sherlock/debugger.h | 6 +++--- engines/sherlock/decompress.cpp | 4 ++-- engines/sherlock/decompress.h | 4 ++-- engines/sherlock/detection.cpp | 4 ++-- engines/sherlock/detection_tables.h | 4 ++-- engines/sherlock/events.cpp | 4 ++-- engines/sherlock/events.h | 4 ++-- engines/sherlock/graphics.cpp | 4 ++-- engines/sherlock/graphics.h | 4 ++-- engines/sherlock/inventory.cpp | 4 ++-- engines/sherlock/inventory.h | 4 ++-- engines/sherlock/journal.cpp | 4 ++-- engines/sherlock/journal.h | 4 ++-- engines/sherlock/map.cpp | 4 ++-- engines/sherlock/map.h | 4 ++-- engines/sherlock/objects.cpp | 4 ++-- engines/sherlock/objects.h | 4 ++-- engines/sherlock/people.cpp | 4 ++-- engines/sherlock/people.h | 4 ++-- engines/sherlock/resources.cpp | 4 ++-- engines/sherlock/resources.h | 4 ++-- engines/sherlock/saveload.cpp | 4 ++-- engines/sherlock/saveload.h | 4 ++-- engines/sherlock/scalpel/darts.cpp | 4 ++-- engines/sherlock/scalpel/darts.h | 4 ++-- engines/sherlock/scalpel/scalpel.cpp | 4 ++-- engines/sherlock/scalpel/scalpel.h | 4 ++-- engines/sherlock/scene.cpp | 4 ++-- engines/sherlock/scene.h | 4 ++-- engines/sherlock/screen.cpp | 4 ++-- engines/sherlock/screen.h | 4 ++-- engines/sherlock/settings.cpp | 4 ++-- engines/sherlock/settings.h | 4 ++-- engines/sherlock/sherlock.cpp | 4 ++-- engines/sherlock/sherlock.h | 4 ++-- engines/sherlock/sound.cpp | 4 ++-- engines/sherlock/sound.h | 4 ++-- engines/sherlock/talk.cpp | 4 ++-- engines/sherlock/talk.h | 4 ++-- engines/sherlock/tattoo/tattoo.cpp | 4 ++-- engines/sherlock/tattoo/tattoo.h | 4 ++-- engines/sherlock/user_interface.cpp | 4 ++-- engines/sherlock/user_interface.h | 4 ++-- 46 files changed, 94 insertions(+), 94 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 299a8186d7..dac903a358 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/animation.h b/engines/sherlock/animation.h index 3d87cb0a91..245d83789f 100644 --- a/engines/sherlock/animation.h +++ b/engines/sherlock/animation.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/debugger.cpp b/engines/sherlock/debugger.cpp index ff9a8056b0..ecd3f2ee08 100644 --- a/engines/sherlock/debugger.cpp +++ b/engines/sherlock/debugger.cpp @@ -8,12 +8,12 @@ * 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 + * 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. diff --git a/engines/sherlock/debugger.h b/engines/sherlock/debugger.h index fe77007975..6021bb7d0d 100644 --- a/engines/sherlock/debugger.h +++ b/engines/sherlock/debugger.h @@ -8,12 +8,12 @@ * 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 + * 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. diff --git a/engines/sherlock/decompress.cpp b/engines/sherlock/decompress.cpp index 7c98b50543..fff9616c60 100644 --- a/engines/sherlock/decompress.cpp +++ b/engines/sherlock/decompress.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/decompress.h b/engines/sherlock/decompress.h index 330e018115..694f56aa65 100644 --- a/engines/sherlock/decompress.h +++ b/engines/sherlock/decompress.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp index a6b980fea3..c38580af41 100644 --- a/engines/sherlock/detection.cpp +++ b/engines/sherlock/detection.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/detection_tables.h b/engines/sherlock/detection_tables.h index b369868741..2f94f78f8a 100644 --- a/engines/sherlock/detection_tables.h +++ b/engines/sherlock/detection_tables.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index 886306fc0e..3b0b0dacc6 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/events.h b/engines/sherlock/events.h index 015c39580d..199e14f03a 100644 --- a/engines/sherlock/events.h +++ b/engines/sherlock/events.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index bdb4df6c83..234928156a 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index 8ed508fad0..91a65c8c43 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index c3e2e14393..af2c4be0e4 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index bec26b333d..f4cea7729a 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 926ccee38a..2ce5f9968a 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h index 2ef0f94492..0ea5218558 100644 --- a/engines/sherlock/journal.h +++ b/engines/sherlock/journal.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index 3879e904fa..5ef6b9220f 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/map.h b/engines/sherlock/map.h index b4e92c600f..4432ec8553 100644 --- a/engines/sherlock/map.h +++ b/engines/sherlock/map.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 35b270dd13..ca8ba1759a 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index f6ad6beb0d..52bd15cbbc 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index f73ebd8cb0..8bf3c1e4c3 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index 02bb8dc950..ee16fab243 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index c64f4e4923..dd906ba132 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h index d53351e085..e1f97f1def 100644 --- a/engines/sherlock/resources.h +++ b/engines/sherlock/resources.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index 61fe9f30bf..a78b89b00c 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/saveload.h b/engines/sherlock/saveload.h index 0865fd3856..c9a7286c6b 100644 --- a/engines/sherlock/saveload.h +++ b/engines/sherlock/saveload.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/scalpel/darts.cpp b/engines/sherlock/scalpel/darts.cpp index 3516a7ae78..6da8d6848e 100644 --- a/engines/sherlock/scalpel/darts.cpp +++ b/engines/sherlock/scalpel/darts.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/scalpel/darts.h b/engines/sherlock/scalpel/darts.h index 50be572067..a9624442e2 100644 --- a/engines/sherlock/scalpel/darts.h +++ b/engines/sherlock/scalpel/darts.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 4cd613d48f..6f7310f573 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h index 2ba47a49e1..40e4937b5d 100644 --- a/engines/sherlock/scalpel/scalpel.h +++ b/engines/sherlock/scalpel/scalpel.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 88f8674913..0893afe4c4 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index c2cca8bad2..8ef5d74785 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index e22c4daad7..2713d192e7 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 7e33a12b7b..501506f8ec 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/settings.cpp b/engines/sherlock/settings.cpp index 2a4d332edf..ffa1f056de 100644 --- a/engines/sherlock/settings.cpp +++ b/engines/sherlock/settings.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/settings.h b/engines/sherlock/settings.h index 90928452c4..25d27d48df 100644 --- a/engines/sherlock/settings.h +++ b/engines/sherlock/settings.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 1a6e84b186..6bfc7ea7d4 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index a516e52ae7..8d02f7aa24 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index 1ee9535f31..24147a0ab9 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index 5c2e8808ee..56cd4ed0a8 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 74bd98c4e1..a1e124aa95 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index b44bccaab6..16cab493f0 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/tattoo/tattoo.cpp b/engines/sherlock/tattoo/tattoo.cpp index b2b45bc310..d4059ac413 100644 --- a/engines/sherlock/tattoo/tattoo.cpp +++ b/engines/sherlock/tattoo/tattoo.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/tattoo/tattoo.h b/engines/sherlock/tattoo/tattoo.h index 6d3ec33967..b98395597c 100644 --- a/engines/sherlock/tattoo/tattoo.h +++ b/engines/sherlock/tattoo/tattoo.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index ce282aa2c2..ec92848c26 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index a0b854af36..79382a19fe 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -8,12 +8,12 @@ * 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. -- cgit v1.2.3 From 1a485a44b8c265cb4e37e235659e1a4e7609d446 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 12:08:45 -0400 Subject: SHERLOCK: Cleanup and fixes for Journal --- engines/sherlock/journal.cpp | 45 ++++++++++++++++++------------------- engines/sherlock/journal.h | 2 +- engines/sherlock/user_interface.cpp | 1 + 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 2ce5f9968a..f7a11f0198 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -75,7 +75,7 @@ void Journal::record(int converseNum, int statementNum, bool replyOnly) { _index = _journal.size() - 1; // Load the text for the new entry to get the number of lines it will have - int newLines = loadJournalFile(true); + loadJournalFile(true); // Restore old state _index = saveIndex; @@ -83,8 +83,8 @@ void Journal::record(int converseNum, int statementNum, bool replyOnly) { // If new lines were added to the ournal, update the total number of lines // the journal continues - if (newLines) { - _maxPage += newLines; + if (!_lines.empty()) { + _maxPage += _lines.size(); } else { // No lines in entry, so remove the new entry from the journal _journal.remove_at(_journal.size() - 1); @@ -135,8 +135,10 @@ void Journal::loadJournalLocations() { /** * Loads the description for the current display index in the journal, and then * word wraps the result to prepare it for being displayed + * @param alreadyLoaded Indicates whether the journal file is being loaded for the + * first time, or being reloaded */ -int Journal::loadJournalFile(bool alreadyLoaded) { +void Journal::loadJournalFile(bool alreadyLoaded) { Screen &screen = *_vm->_screen; Talk &talk = *_vm->_talk; JournalEntry &journalEntry = _journal[_index]; @@ -448,8 +450,6 @@ int Journal::loadJournalFile(bool alreadyLoaded) { } else { _lines.clear(); } - - return _lines.size(); } /** @@ -562,7 +562,6 @@ bool Journal::doJournal(int direction, int howFar) { bool searchSuccessful = false; bool endFlag = false; int lineNum = 0; - int maxLines; int savedIndex; int temp; const char *matchP; @@ -573,18 +572,18 @@ bool Journal::doJournal(int direction, int howFar) { do { // Get the number of lines for the current journal entry - maxLines = loadJournalFile(false); - if (!maxLines) { + loadJournalFile(false); + if (_lines.empty()) { // Entry has no text, so it must be a stealth eny. Move onto further journal entries // until an entry with text is found if (++_index == (int)_journal.size()) { endJournal = true; } else { _sub = 0; - maxLines = loadJournalFile(false); + loadJournalFile(false); } } - } while (!endJournal && !maxLines); + } while (!endJournal && _lines.empty()); // Check if there no further pages with text until the end of the journal if (endJournal) { @@ -621,14 +620,14 @@ bool Journal::doJournal(int direction, int howFar) { endJournal = true; } else { - maxLines = loadJournalFile(false); - _sub = maxLines - 1; + loadJournalFile(false); + _sub = _lines.size() - 1; } - } while (!endJournal && !maxLines); + } while (!endJournal && _lines.empty()); } // If it's search mode, check each line for the given keyword - if (direction >= 3 && maxLines && !endJournal && !searchSuccessful) { + if (direction >= 3 && !_lines.empty() && !endJournal && !searchSuccessful) { Common::String line = _lines[_sub]; line.toUppercase(); if (strstr(line.c_str(), _find.c_str()) != nullptr) { @@ -675,19 +674,19 @@ bool Journal::doJournal(int direction, int howFar) { // Move forwards a line at a time, unless search word was found if (!searchSuccessful) { - if (++_sub == maxLines) { + if (++_sub == (int)_lines.size()) { // Reached end of page do { if (++_index == (int)_journal.size()) { _index = savedIndex; _sub = savedSub; - maxLines = loadJournalFile(false); + loadJournalFile(false); endJournal = true; } else { _sub = 0; - maxLines = loadJournalFile(false); + loadJournalFile(false); } - } while (!endJournal && !maxLines); + } while (!endJournal && _lines.empty()); } ++lineNum; @@ -702,7 +701,7 @@ bool Journal::doJournal(int direction, int howFar) { // Search found, so show top of the page it was found on _index = savedIndex; _sub = savedSub; - maxLines = loadJournalFile(false); + loadJournalFile(false); } } break; @@ -769,19 +768,19 @@ bool Journal::doJournal(int direction, int howFar) { } } - if (++temp == maxLines) { + if (++temp == (int)_lines.size()) { // Move to next page do { if (_index < ((int)_journal.size() - 1) && lineNum < (LINES_PER_PAGE - 1)) { ++_index; - maxLines = loadJournalFile(false); + loadJournalFile(false); temp = 0; } else { if (_index == ((int)_journal.size() - 1)) _down = false; endFlag = true; } - } while (!endFlag && !maxLines); + } while (!endFlag && _lines.empty()); } if (inc) { diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h index 0ea5218558..c4112e5617 100644 --- a/engines/sherlock/journal.h +++ b/engines/sherlock/journal.h @@ -60,7 +60,7 @@ private: void loadJournalLocations(); - int loadJournalFile(bool alreadyLoaded); + void loadJournalFile(bool alreadyLoaded); void doArrows(); diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index ec92848c26..674141f171 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1825,6 +1825,7 @@ void UserInterface::journalControl() { _windowOpen = false; _windowBounds.top = CONTROLS_Y1; _key = -1; + _menuMode = STD_MODE; // Reset the palette screen.setPalette(screen._cMap); -- cgit v1.2.3 From 825677415319486ed35c8591c106f66ad53b710f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 12:19:05 -0400 Subject: SHERLOCK: Method renames in Journal for better clarity --- engines/sherlock/journal.cpp | 44 ++++++++++++++++++++++---------------------- engines/sherlock/journal.h | 4 ++-- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index f7a11f0198..984a7a23f6 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -453,9 +453,9 @@ void Journal::loadJournalFile(bool alreadyLoaded) { } /** - * Draw the journal frame + * Draw the journal background, frame, and interface buttons */ -void Journal::drawJournal() { +void Journal::drawJournalFrame() { Resources &res = *_vm->_res; Screen &screen = *_vm->_screen; byte palette[PALETTE_SIZE]; @@ -511,12 +511,12 @@ void Journal::drawJournal() { void Journal::drawInterface() { Screen &screen = *_vm->_screen; - drawJournal(); + drawJournalFrame(); if (_journal.size() == 0) { _up = _down = 0; } else { - doJournal(0, 0); + drawJournal(0, 0); } doArrows(); @@ -552,7 +552,7 @@ void Journal::doArrows() { /** * Displays a page of the journal at the current index */ -bool Journal::doJournal(int direction, int howFar) { +bool Journal::drawJournal(int direction, int howFar) { Events &events = *_vm->_events; Screen &screen = *_vm->_screen; int yp = 37; @@ -589,7 +589,7 @@ bool Journal::doJournal(int direction, int howFar) { if (endJournal) { // If moving forward or backwards, clear the page before printing if (direction) - drawJournal(); + drawJournalFrame(); screen.gPrint(Common::Point(235, 21), PEN_COLOR, "Page %d", _page); return false; @@ -712,7 +712,7 @@ bool Journal::doJournal(int direction, int howFar) { if (direction) { events.setCursor(ARROW); - drawJournal(); + drawJournalFrame(); } screen.gPrint(Common::Point(235, 21), PEN_COLOR, "Page %d", _page); @@ -915,9 +915,9 @@ bool Journal::handleEvents(int key) { if (((found == BTN_BACK10 && events._released) || key == 'B') && (_page > 1)) { // Scrolll up 10 pages if (_page < 11) - doJournal(1, (_page - 1) * LINES_PER_PAGE); + drawJournal(1, (_page - 1) * LINES_PER_PAGE); else - doJournal(1, 10 * LINES_PER_PAGE); + drawJournal(1, 10 * LINES_PER_PAGE); doArrows(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); @@ -925,14 +925,14 @@ bool Journal::handleEvents(int key) { if (((found == BTN_UP && events._released) || key =='U') && _up) { // Scroll up - doJournal(1, LINES_PER_PAGE); + drawJournal(1, LINES_PER_PAGE); doArrows(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } if (((found == BTN_DOWN && events._released) || key =='D') && _down) { // Scroll down - doJournal(2, LINES_PER_PAGE); + drawJournal(2, LINES_PER_PAGE); doArrows(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } @@ -940,9 +940,9 @@ bool Journal::handleEvents(int key) { if (((found == BTN_AHEAD110 && events._released) || key == 'A') && _down) { // Scroll down 10 pages if ((_page + 10) > _maxPage) - doJournal(2, (_maxPage - _page) * LINES_PER_PAGE); + drawJournal(2, (_maxPage - _page) * LINES_PER_PAGE); else - doJournal(2, 10 * LINES_PER_PAGE); + drawJournal(2, 10 * LINES_PER_PAGE); doArrows(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); @@ -960,13 +960,13 @@ bool Journal::handleEvents(int key) { int savedSub = _sub; int savedPage = _page; - if (doJournal(dir + 2, 1000 * LINES_PER_PAGE) == 0) { + if (drawJournal(dir + 2, 1000 * LINES_PER_PAGE) == 0) { _index = savedIndex; _sub = savedSub; _page = savedPage; - drawJournal(); - doJournal(0, 0); + drawJournalFrame(); + drawJournal(0, 0); notFound = true; } else { doneFlag = true; @@ -987,8 +987,8 @@ bool Journal::handleEvents(int key) { _up = _down = false; _page = 1; - drawJournal(); - doJournal(0, 0); + drawJournalFrame(); + drawJournal(0, 0); doArrows(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } @@ -996,9 +996,9 @@ bool Journal::handleEvents(int key) { if (((found == BTN_LAST_PAGE && events._released) || key == 'L') && _down) { // Last page if ((_page + 10) > _maxPage) - doJournal(2, (_maxPage - _page) * LINES_PER_PAGE); + drawJournal(2, (_maxPage - _page) * LINES_PER_PAGE); else - doJournal(2, 1000 * LINES_PER_PAGE); + drawJournal(2, 1000 * LINES_PER_PAGE); doArrows(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); @@ -1170,8 +1170,8 @@ int Journal::getFindName(bool printError) { } // Redisplay the journal screen - drawJournal(); - doJournal(0, 0); + drawJournalFrame(); + drawJournal(0, 0); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); return done; diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h index c4112e5617..ac4391b8f3 100644 --- a/engines/sherlock/journal.h +++ b/engines/sherlock/journal.h @@ -64,11 +64,11 @@ private: void doArrows(); - bool doJournal(int direction, int howFar); + bool drawJournal(int direction, int howFar); int getFindName(bool printError); - void drawJournal(); + void drawJournalFrame(); public: Journal(SherlockEngine *vm); -- cgit v1.2.3 From 0629ae4639651f546d6aeb56bac842fd07939b8f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 12:26:47 -0400 Subject: SHERLOCK: Fix display of Forward text in Journal --- engines/sherlock/journal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 984a7a23f6..71de9228e4 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -1115,7 +1115,7 @@ int Journal::getFindName(bool printError) { } else { color = COMMAND_FOREGROUND; } - screen.print(Common::Point(SEARCH_POINTS[1][2] - screen.stringWidth("Forward") / 2, 175), color, "Forward"); + screen.print(Common::Point(SEARCH_POINTS[2][2] - screen.stringWidth("Forward") / 2, 175), color, "Forward"); } events.wait(2); -- cgit v1.2.3 From 66a1138d742bc96eb5abb81dea7aab39d89a8a04 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 12:34:08 -0400 Subject: SHERLOCK: Disable Journal Print Text button, since it isn't supported --- engines/sherlock/journal.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 71de9228e4..a9252d111a 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -500,9 +500,13 @@ void Journal::drawJournalFrame() { screen.makeButton(Common::Rect(JOURNAL_POINTS[7][0], JOURNAL_BUTTONS_Y + 11, JOURNAL_POINTS[7][1], JOURNAL_BUTTONS_Y + 21), JOURNAL_POINTS[7][2] - screen.stringWidth("Last Page") / 2, "Last Page"); + + // WORKAROUND: Draw Print Text button as disabled, since we don't support it in ScummVM screen.makeButton(Common::Rect(JOURNAL_POINTS[8][0], JOURNAL_BUTTONS_Y + 11, JOURNAL_POINTS[8][1], JOURNAL_BUTTONS_Y + 21), JOURNAL_POINTS[8][2] - screen.stringWidth("Print Text") / 2, "Print Text"); + screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11), + COMMAND_NULL, false, "Print Text"); } /** @@ -543,7 +547,7 @@ void Journal::doArrows() { color = _journal.size() > 0 ? COMMAND_FOREGROUND : COMMAND_NULL; screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), color, false, "Search"); - screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11), color, false, "Print Text"); + screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11), COMMAND_NULL, false, "Print Text"); color = _page > 1 ? COMMAND_FOREGROUND : COMMAND_NULL; screen.buttonPrint(Common::Point(JOURNAL_POINTS[6][2], JOURNAL_BUTTONS_Y + 11), color, false, "First Page"); @@ -899,13 +903,8 @@ bool Journal::handleEvents(int key) { if (pt.x > JOURNAL_POINTS[8][0] && pt.x < JOURNAL_POINTS[8][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) && pt.y < (JOURNAL_BUTTONS_Y + 20) && !_journal.empty()) { found = BTN_PRINT_TEXT; - color = COMMAND_HIGHLIGHTED; - } else if (_journal.empty()) { - color = COMMAND_NULL; - } else { - color = COMMAND_FOREGROUND; } - screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11), color, true, "Print Text"); + screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11), COMMAND_NULL, true, "Print Text"); } if (found == BTN_EXIT && events._released) -- cgit v1.2.3 From eeb53ca614823896ef6c43f9f9d7580cbb6e0d78 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 12:58:44 -0400 Subject: SHERLOCK: Remove duplicated _converseNum field from Journal --- engines/sherlock/journal.cpp | 10 +++++----- engines/sherlock/journal.h | 1 - engines/sherlock/talk.h | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index a9252d111a..2a7aeb4f2d 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -56,7 +56,6 @@ Journal::Journal(SherlockEngine *vm): _vm(vm) { _sub = 0; _up = _down = false; _page = 1; - _converseNum = -1; // Load the journal directory and location names loadJournalLocations(); @@ -151,11 +150,11 @@ void Journal::loadJournalFile(bool alreadyLoaded) { // If not flagged as alrady loaded, load the conversation into script variables if (!alreadyLoaded) { // See if the file to be used is already loaded - if (journalEntry._converseNum != _converseNum) { + if (journalEntry._converseNum != talk._converseNum) { // Nope. Free any previously loaded talk talk.freeTalkVars(); - // Find the person being talked to + // Find the person being referred to talk._talkTo = -1; for (int idx = 0; idx < MAX_PEOPLE; ++idx) { Common::String portrait = PORTRAITS[idx]; @@ -167,7 +166,7 @@ void Journal::loadJournalFile(bool alreadyLoaded) { } } - // Load the talk file + // Load their talk file talk.loadTalkFile(dirFilename); } } @@ -559,6 +558,7 @@ void Journal::doArrows() { bool Journal::drawJournal(int direction, int howFar) { Events &events = *_vm->_events; Screen &screen = *_vm->_screen; + Talk &talk = *_vm->_talk; int yp = 37; int startPage = _page; bool endJournal = false; @@ -571,7 +571,7 @@ bool Journal::drawJournal(int direction, int howFar) { const char *matchP; int width; - _converseNum = -1; + talk._converseNum = -1; _down = true; do { diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h index ac4391b8f3..be5c4d77c3 100644 --- a/engines/sherlock/journal.h +++ b/engines/sherlock/journal.h @@ -55,7 +55,6 @@ private: int _sub; bool _up, _down; int _page; - int _converseNum; Common::String _find; void loadJournalLocations(); diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index 16cab493f0..d81586228f 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -137,7 +137,6 @@ private: int _speaker; int _talkIndex; int _scriptSelect; - int _converseNum; int _talkStealth; int _talkToFlag; int _scriptSaveIndex; @@ -160,6 +159,7 @@ public: int _scriptMoreFlag; Common::String _scriptName; bool _moreTalkUp, _moreTalkDown; + int _converseNum; public: Talk(SherlockEngine *vm); void setSequences(const byte *talkSequences, const byte *stillSequences, -- cgit v1.2.3 From 3e2b0bfb69027eaa3c4d47ac06dba3310b671c08 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 12:59:51 -0400 Subject: SHERLOCK: Remove unused getGameType method declaration --- engines/sherlock/sherlock.h | 1 - 1 file changed, 1 deletion(-) diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 8d02f7aa24..5a3ed4bc1f 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -120,7 +120,6 @@ public: virtual Common::Error saveGameState(int slot, const Common::String &desc); virtual void syncSoundSettings(); - int getGameType() const; GameType getGameID() const; Common::Language getLanguage() const; Common::Platform getPlatform() const; -- cgit v1.2.3 From d50fb7cb602e826cddf9ceb76608cba1a54d943b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 13:03:28 -0400 Subject: SHERLOCK: Updated module.mk to match that of other engines --- engines/sherlock/module.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk index 9334ebfd9c..babd0c49a0 100644 --- a/engines/sherlock/module.mk +++ b/engines/sherlock/module.mk @@ -26,7 +26,7 @@ MODULE_OBJS = \ user_interface.o # This module can be built as a plugin -ifdef BUILD_PLUGINS +ifeq ($(ENABLE_SHERLOCK), DYNAMIC_PLUGIN) PLUGIN := 1 endif -- cgit v1.2.3 From 1ba94c93e98533f3bfc2970d6ae40356515b99b9 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 13:07:14 -0400 Subject: SHERLOCK: Remove redundant shouldQuit call in loop --- engines/sherlock/people.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 8bf3c1e4c3..0eda40c03f 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -306,7 +306,7 @@ void People::setWalking() { // If the player is already close to the given destination that no // walking is needed, move to the next straight line segment in the // overall walking route, if there is one - do { + for (;;) { // Since we want the player to be centered on the destination they // clicked, but characters draw positions start at their left, move // the destination half the character width to draw him centered @@ -326,7 +326,7 @@ void People::setWalking() { // Pop next walk segment off the walk route stack _walkDest = _walkTo.pop(); - } while (!_vm->shouldQuit()); + } // If a sufficient move is being done, then start the move if (delta.x > 3 || delta.y) { -- cgit v1.2.3 From 6925b848d6bb8f93c6be3cc1d32780e729c6d242 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 15:48:19 -0400 Subject: SHERLOCK: Fix getting fresh mouse positions in loop showing quit dialog --- engines/sherlock/user_interface.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 674141f171..8b3ee426a4 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -936,6 +936,8 @@ void UserInterface::doEnvControl() { events.pollEventsAndWait(); events.setButtonState(); + mousePos = events.mousePos(); + if (events.kbHit()) { Common::KeyState keyState = events.getKey(); _key = toupper(keyState.keycode); -- cgit v1.2.3 From 1ddbe9d720d96baf3f95373d264ff1218b34411f Mon Sep 17 00:00:00 2001 From: Strangerke Date: Sat, 9 May 2015 21:31:12 +0200 Subject: SHERLOCK: Add some detection entries --- engines/sherlock/detection_tables.h | 47 ++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/detection_tables.h b/engines/sherlock/detection_tables.h index 2f94f78f8a..752ef8d5cf 100644 --- a/engines/sherlock/detection_tables.h +++ b/engines/sherlock/detection_tables.h @@ -24,7 +24,7 @@ namespace Sherlock { static const SherlockGameDescription gameDescriptions[] = { { - // Case of the Serrated Scalpel - English + // Case of the Serrated Scalpel - English 3.5" Floppy { "scalpel", 0, @@ -37,6 +37,51 @@ static const SherlockGameDescription gameDescriptions[] = { GType_SerratedScalpel, }, + { + // Case of the Serrated Scalpel - Interactive English Demo + // Provided by Strangerke + { + "scalpel", + "Interactive Demo", + AD_ENTRY1s("talk.lib", "dbdc8a20c96900aa7e4d02f3fe8a274c", 121102), + Common::EN_ANY, + Common::kPlatformDOS, + ADGF_DEMO, + GUIO1(GUIO_NOSPEECH) + }, + GType_SerratedScalpel, + }, + + { + // Case of the Serrated Scalpel - Non-Interactive English Demo + // Provided by Strangerke + { + "scalpel", + "Non Interactive Demo", + AD_ENTRY1s("music.lib", "ec19a09b7fef6fd90b1ab812ce6e9739", 38563), + Common::EN_ANY, + Common::kPlatformDOS, + ADGF_DEMO, + GUIO1(GUIO_NOSPEECH) + }, + GType_SerratedScalpel, + }, + + { + // Case of the Rose Tattoo - French CD + // Provided by Strangerke + { + "rosetattoo", + 0, + AD_ENTRY1s("talk.lib", "22e8e6406dd2fbbb238c9898928df42e", 770756), + Common::EN_ANY, + Common::kPlatformDOS, + ADGF_NO_FLAGS, + GUIO1(GUIO_NONE) + }, + GType_RoseTattoo, + }, + { AD_TABLE_END_MARKER, (GameType)0 } }; -- cgit v1.2.3 From 281d44706bfa2cb58b3de469d320f06f75a93c86 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 15:53:18 -0400 Subject: SHERLOCK: Refine comment for decompressLZ --- engines/sherlock/decompress.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/decompress.cpp b/engines/sherlock/decompress.cpp index fff9616c60..dfa573209f 100644 --- a/engines/sherlock/decompress.cpp +++ b/engines/sherlock/decompress.cpp @@ -27,8 +27,8 @@ namespace Sherlock { /** * Decompresses an LZW compressed resource. If no outSize is specified, it will * decompress the entire resource. If, however, an explicit size is specified, - * it will decompress only up to that many bytes from the stream starting at - * whatever position it was previously. + * then it means we're already within a resource, and only want to decompress + * part of it. */ Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source, int32 outSize) { if (outSize == -1) { -- cgit v1.2.3 From 7107789c473a96678f408902b1a3b6eb2c86f69f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 15:59:31 -0400 Subject: SHERLOCK: Further cleanup of detection entries and added Rose Tattoo English --- engines/sherlock/detection_tables.h | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/engines/sherlock/detection_tables.h b/engines/sherlock/detection_tables.h index 752ef8d5cf..0b41bfad0e 100644 --- a/engines/sherlock/detection_tables.h +++ b/engines/sherlock/detection_tables.h @@ -31,7 +31,7 @@ static const SherlockGameDescription gameDescriptions[] = { AD_ENTRY1s("talk.lib", "ad0c4d6865edf15da4e9204c08815875", 238928), Common::EN_ANY, Common::kPlatformDOS, - ADGF_NO_FLAGS, + ADGF_UNSTABLE | ADGF_NO_FLAGS, GUIO1(GUIO_NOSPEECH) }, GType_SerratedScalpel, @@ -46,7 +46,7 @@ static const SherlockGameDescription gameDescriptions[] = { AD_ENTRY1s("talk.lib", "dbdc8a20c96900aa7e4d02f3fe8a274c", 121102), Common::EN_ANY, Common::kPlatformDOS, - ADGF_DEMO, + ADGF_UNSTABLE | ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, GType_SerratedScalpel, @@ -61,7 +61,7 @@ static const SherlockGameDescription gameDescriptions[] = { AD_ENTRY1s("music.lib", "ec19a09b7fef6fd90b1ab812ce6e9739", 38563), Common::EN_ANY, Common::kPlatformDOS, - ADGF_DEMO, + ADGF_UNSTABLE | ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, GType_SerratedScalpel, @@ -72,12 +72,25 @@ static const SherlockGameDescription gameDescriptions[] = { // Provided by Strangerke { "rosetattoo", - 0, + "CD", AD_ENTRY1s("talk.lib", "22e8e6406dd2fbbb238c9898928df42e", 770756), Common::EN_ANY, Common::kPlatformDOS, - ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + ADGF_UNSTABLE, + GUIO0() + } + }, + + { + // Case of the Rose Tattoo - English CD + { + "rosetattoo", + "CD", + AD_ENTRY1s("talk.lib", "9639a756b0993ebd71cb5f4d8b78b2dc", 765134), + Common::EN_ANY, + Common::kPlatformDOS, + ADGF_UNSTABLE, + GUIO0() }, GType_RoseTattoo, }, -- cgit v1.2.3 From 3b76b8634a8272caf6a188527d88a5c5eb9ae5d1 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 16:46:39 -0400 Subject: SHERLOCK: Fix incorrect comment --- engines/sherlock/scalpel/scalpel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 6f7310f573..0b7a9be278 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -505,7 +505,7 @@ void ScalpelEngine::showLBV(const Common::String &filename) { */ void ScalpelEngine::startScene() { if (_scene->_goToScene == 100 || _scene->_goToScene == 98) { - // Chessboard selection + // Show the map if (_sound->_musicOn) { if (_sound->loadSong(100)) { if (_sound->_music) -- cgit v1.2.3 From 13c6feae3538aab7f5bffe2253d34ca256ac8314 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Sun, 10 May 2015 00:07:41 +0200 Subject: SHERLOCK: Add comment about HitSquad CD in the detection --- engines/sherlock/detection_tables.h | 1 + 1 file changed, 1 insertion(+) diff --git a/engines/sherlock/detection_tables.h b/engines/sherlock/detection_tables.h index 0b41bfad0e..260869660e 100644 --- a/engines/sherlock/detection_tables.h +++ b/engines/sherlock/detection_tables.h @@ -25,6 +25,7 @@ namespace Sherlock { static const SherlockGameDescription gameDescriptions[] = { { // Case of the Serrated Scalpel - English 3.5" Floppy + // The HitSquad CD version has the same MD5 { "scalpel", 0, -- cgit v1.2.3 From 6d110485bc2573db524ceb5aff9f4816d00460b2 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 May 2015 18:19:28 -0400 Subject: SHERLOCK: Performance tweak for resource loading --- engines/sherlock/map.cpp | 3 ++- engines/sherlock/resources.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index 5ef6b9220f..ef262aabd3 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -96,7 +96,8 @@ void Map::loadData() { // Load the list of location names Common::SeekableReadStream *txtStream = _vm->_res->load("chess.txt"); - while (txtStream->pos() < txtStream->size()) { + int streamSize = txtStream->size(); + while (txtStream->pos() < streamSize) { Common::String line; char c; while ((c = txtStream->readByte()) != '\0') diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index dd906ba132..3f74590386 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -293,7 +293,8 @@ ImageFile::~ImageFile() { void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette, bool animImages) { loadPalette(stream); - while (stream.pos() < stream.size()) { + int streamSize = stream.size(); + while (stream.pos() < streamSize) { ImageFrame frame; frame._width = stream.readUint16LE() + 1; frame._height = stream.readUint16LE() + 1; -- cgit v1.2.3 From 1f81f61cf9c6dffe5918f293627f7b8fa34be1cd Mon Sep 17 00:00:00 2001 From: Strangerke Date: Sun, 10 May 2015 19:14:55 +0200 Subject: SHERLOCK: Add some code for the interactive demo (still crashing) --- engines/sherlock/detection.cpp | 7 +++++++ engines/sherlock/detection_tables.h | 1 + engines/sherlock/map.cpp | 3 ++- engines/sherlock/scalpel/scalpel.cpp | 10 +++++++++- engines/sherlock/scene.cpp | 10 ++++++---- 5 files changed, 25 insertions(+), 6 deletions(-) diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp index c38580af41..78ab33bfd0 100644 --- a/engines/sherlock/detection.cpp +++ b/engines/sherlock/detection.cpp @@ -122,6 +122,13 @@ bool Sherlock::SherlockEngine::hasFeature(EngineFeature f) const { (f == kSupportsSavingDuringRuntime); } +/** + * Returns whether the version is a demo + */ +bool Sherlock::SherlockEngine::getIsDemo() const { + return _gameDescription->desc.flags & ADGF_DEMO; +} + /** * Return a list of savegames */ diff --git a/engines/sherlock/detection_tables.h b/engines/sherlock/detection_tables.h index 260869660e..975b7323ec 100644 --- a/engines/sherlock/detection_tables.h +++ b/engines/sherlock/detection_tables.h @@ -84,6 +84,7 @@ static const SherlockGameDescription gameDescriptions[] = { { // Case of the Rose Tattoo - English CD + // Provided by dreammaster { "rosetattoo", "CD", diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index ef262aabd3..e178dece0c 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -69,7 +69,8 @@ Map::Map(SherlockEngine *vm): _vm(vm), _topLine(SHERLOCK_SCREEN_WIDTH, 12) { for (int idx = 0; idx < MAX_HOLMES_SEQUENCE; ++idx) Common::fill(&_sequences[idx][0], &_sequences[idx][MAX_FRAME], 0); - loadData(); + if (!_vm->getIsDemo()) + loadData(); } /** diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 0b7a9be278..8dc75c034f 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -215,9 +215,11 @@ void ScalpelEngine::initialize() { _flags[3] = true; // Turn on Alley _flags[39] = true; // Turn on Baker Street + if (!getIsDemo()) { // Load the map co-ordinates for each scene and sequence data _map->loadPoints(NUM_PLACES, &MAP_X[0], &MAP_Y[0], &MAP_TRANSLATE[0]); _map->loadSequences(3, &MAP_SEQUENCES[0][0]); + } // Load the inventory loadInventory(); @@ -226,13 +228,19 @@ void ScalpelEngine::initialize() { _talk->setSequences(&TALK_SEQUENCES[0][0], &STILL_SEQUENCES[0][0], MAX_PEOPLE); // Starting scene - _scene->_goToScene = 4; + if (getIsDemo()) + _scene->_goToScene = 3; + else + _scene->_goToScene = 4; } /** * Show the opening sequence */ void ScalpelEngine::showOpening() { + if (getIsDemo()) + return; + if (!showCityCutscene()) return; if (!showAlleyCutscene()) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 0893afe4c4..ca9f19582c 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -457,10 +457,12 @@ bool Scene::loadScene(const Common::String &filename) { _walkedInScene = false; saves._justLoaded = false; - // Reset the previous map location and position on overhead map - map._oldCharPoint = _currentScene; - map._overPos.x = map[_currentScene].x * 100 - 600; - map._overPos.y = map[_currentScene].y * 100 + 900; + if (!_vm->getIsDemo()) { + // Reset the previous map location and position on overhead map + map._oldCharPoint = _currentScene; + map._overPos.x = map[_currentScene].x * 100 - 600; + map._overPos.y = map[_currentScene].y * 100 + 900; + } events.clearEvents(); return flag; -- cgit v1.2.3 From eae3ff961001b9ce071873978e29310947d2212b Mon Sep 17 00:00:00 2001 From: Strangerke Date: Sun, 10 May 2015 19:46:15 +0200 Subject: SHERLOCK: Fix compilation (sorry for the noise) --- engines/sherlock/sherlock.h | 1 + 1 file changed, 1 insertion(+) diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 5a3ed4bc1f..501fdcb292 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -119,6 +119,7 @@ public: virtual Common::Error loadGameState(int slot); virtual Common::Error saveGameState(int slot, const Common::String &desc); virtual void syncSoundSettings(); + virtual bool getIsDemo() const; GameType getGameID() const; Common::Language getLanguage() const; -- cgit v1.2.3 From 0d3750a768c8f9457530344fa6871b98dd20276b Mon Sep 17 00:00:00 2001 From: Strangerke Date: Mon, 11 May 2015 01:04:04 +0200 Subject: SHERLOCK: Add preliminar sound support --- engines/sherlock/sherlock.cpp | 2 +- engines/sherlock/sound.cpp | 112 ++++++++++++++++++++++++++++++++++++++++-- engines/sherlock/sound.h | 13 ++++- 3 files changed, 119 insertions(+), 8 deletions(-) diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 6bfc7ea7d4..2a5d9ec627 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -89,7 +89,7 @@ void SherlockEngine::initialize() { _saves = new SaveManager(this, _targetName); _scene = new Scene(this); _screen = new Screen(this); - _sound = new Sound(this); + _sound = new Sound(this, _mixer); _talk = new Talk(this); _ui = new UserInterface(this); diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index 24147a0ab9..51563d17a6 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -23,10 +23,14 @@ #include "sherlock/sherlock.h" #include "sherlock/sound.h" #include "common/config-manager.h" +#include "audio/audiostream.h" +#include "common/algorithm.h" +#include "audio/mixer.h" +#include "audio/decoders/raw.h" namespace Sherlock { -Sound::Sound(SherlockEngine *vm): _vm(vm) { +Sound::Sound(SherlockEngine *vm, Audio::Mixer *mixer): _vm(vm), _mixer(mixer) { _digitized = false; _music = false; _voices = 0; @@ -38,6 +42,9 @@ Sound::Sound(SherlockEngine *vm): _vm(vm) { _soundOn = true; _musicOn = true; _speechOn = true; + + _vm->_res->addToCache("MUSIC.LIB"); + _vm->_res->addToCache("SND.SND"); } /** @@ -54,10 +61,91 @@ void Sound::loadSound(const Common::String &name, int priority) { warning("TODO: Sound::loadSound"); } +char Sound::decodeSample(char sample, byte& prediction, int& step) { + char diff = ((sample & 0x07) << step); + + if (sample & 0x08) { + if (prediction > diff) + prediction = prediction - ((sample & 0x07) << step); + else + prediction = 0; + } else { + if (prediction < 0xff - diff) + prediction = prediction + ((sample&0x07) << step); + else + prediction = 0xff; + } + + + if ((sample & 0x07) >= 5 && step < 3) { + step ++; + } else if ((sample & 0x07) == 0 && step > 0) { + step --; + } + + return prediction; +} + bool Sound::playSound(const Common::String &name, WaitType waitType) { - // TODO - warning("TODO: Sound::playSound"); - return true; + _mixer->stopHandle(_effectsHandle); + + Common::String filename = name; + if (!filename.contains('.')) + filename += ".SND"; + Common::SeekableReadStream *stream = _vm->_res->load(filename, "TITLE.SND"); + + stream->skip(2); + int size = stream->readUint32BE(); + int rate = stream->readUint16BE(); + byte *data = (byte *)malloc(size); + byte *ptr = data; + stream->read(ptr, size); + + byte *decoded = (byte *)malloc((size - 1) * 2); + + // +127 to eliminate the pop when the sound starts (signed vs unsignded PCM). Still does not help with the pop at the end + byte prediction = (ptr[0] & 0x0f) + 127; + int step = 0; + int counter = 0; + + for(int i = 1; i < size; i++) { + decoded[counter++] = decodeSample((ptr[i]>>4)&0x0f, prediction, step); + decoded[counter++] = decodeSample((ptr[i]>>0)&0x0f, prediction, step); + } + + free(data); + + Audio::AudioStream *audioStream = Audio::makeRawStream(decoded, (size - 2) * 2, rate, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES); + _mixer->playStream(Audio::Mixer::kPlainSoundType, &_effectsHandle, audioStream, -1, Audio::Mixer::kMaxChannelVolume); + _soundPlaying = true; + + if (waitType == WAIT_RETURN_IMMEDIATELY) { + _diskSoundPlaying = true; + return true; + } + + bool retval = true; + do { + _vm->_events->pollEvents(); + g_system->delayMillis(10); + if ((waitType == WAIT_KBD_OR_FINISH) && _vm->_events->kbHit()) { + retval = false; + break; + } + } while (!_vm->shouldQuit() && _mixer->isSoundHandleActive(_effectsHandle)); + + _soundPlaying = false; + _mixer->stopHandle(_effectsHandle); + +#if 0 + // Debug : used to dump files + Common::DumpFile outFile; + outFile.open(filename); + outFile.write(decoded, (size - 2) * 2); + outFile.flush(); + outFile.close(); +#endif + return retval; } void Sound::cacheSound(const Common::String &name, int index) { @@ -92,7 +180,21 @@ void Sound::stopSound() { void Sound::playMusic(const Common::String &name) { // TODO - warning("TODO: Sound::playMusic"); + warning("Sound::playMusic %s", name.c_str()); + Common::SeekableReadStream *stream = _vm->_res->load(name, "MUSIC.LIB"); + + byte *data = new byte[stream->size()]; + byte *ptr = data; + stream->read(ptr, stream->size()); + Common::DumpFile outFile; + outFile.open(name + ".RAW"); + outFile.write(data, stream->size()); + outFile.flush(); + outFile.close(); + delete[] data; + + stopMusic(); + startSong(); } void Sound::stopMusic() { diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index 56cd4ed0a8..213a6f7a1e 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -25,6 +25,11 @@ #include "common/scummsys.h" #include "common/str.h" +#include "audio/audiostream.h" +#include "audio/mixer.h" +#include "access/files.h" +#include "audio/midiplayer.h" +#include "audio/midiparser.h" namespace Sherlock { @@ -37,6 +42,10 @@ enum WaitType { class Sound { private: SherlockEngine *_vm; + Audio::Mixer *_mixer; + Audio::SoundHandle _effectsHandle; + + char decodeSample(char sample, byte& prediction, int& step); public: bool _digitized; bool _music; @@ -50,7 +59,7 @@ public: bool *_soundIsOn; byte *_digiBuf; public: - Sound(SherlockEngine *vm); + Sound(SherlockEngine *vm, Audio::Mixer *mixer); void syncSoundSettings(); void loadSound(const Common::String &name, int priority); @@ -64,7 +73,7 @@ public: int loadSong(int songNumber); void startSong(); void freeSong(); - + void playMusic(const Common::String &name); void stopMusic(); void stopSndFuncPtr(int v1, int v2); -- cgit v1.2.3 From 7b2da2abc58866d6ad33730d2237bc0decf4ae0e Mon Sep 17 00:00:00 2001 From: sirlemonhead Date: Tue, 12 May 2015 00:42:57 +0100 Subject: SHERLOCK: Re-factored Scalpel arrays out of Animation --- engines/sherlock/animation.cpp | 87 ++++++++++++++++++++---------------- engines/sherlock/animation.h | 15 +++++++ engines/sherlock/scalpel/scalpel.cpp | 41 +++++++++++++++++ 3 files changed, 104 insertions(+), 39 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index dac903a358..5c11c4f6fb 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -26,39 +26,6 @@ namespace Sherlock { -// The following are a list of filenames played in the prologue that have -// special effects associated with them at specific frames - -#define FRAMES_END 32000 -#define PROLOGUE_NAMES_COUNT 6 -#define TITLE_NAMES_COUNT 7 -static const char *const PROLOGUE_NAMES[6] = { - "subway1", "subway2", "finale2", "suicid", "coff3", "coff4" -}; -static const int PROLOGUE_FRAMES[6][9] = { - { 4, 26, 54, 72, 92, 134, FRAMES_END }, - { 2, 80, 95, 117, 166, FRAMES_END }, - { 1, FRAMES_END }, - { 42, FRAMES_END }, - { FRAMES_END }, - { FRAMES_END } -}; - -// Title animations file list -static const char *const TITLE_NAMES[7] = { - "27pro1", "14note", "coff1", "coff2", "coff3", "coff4", "14kick" -}; - -static const int TITLE_FRAMES[7][9] = { - { 29, 131, FRAMES_END }, - { 55, 80, 95, 117, 166, FRAMES_END }, - { 15, FRAMES_END }, - { 4, 37, 92, FRAMES_END }, - { 2, 43, FRAMES_END }, - { 2, FRAMES_END }, - { 10, 50, FRAMES_END } -}; - static const int NO_FRAMES = FRAMES_END; Animation::Animation(SherlockEngine *vm): _vm(vm) { @@ -171,6 +138,48 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade, return !skipped && !_vm->shouldQuit(); } +/** + * Load the prologue name array + */ +void Animation::setPrologueNames(const char *const *names, int count) { + for (int idx = 0; idx < count; ++idx, names++) { + _prologueNames.push_back(*names); + } +} + +/** + * Load the prologue frame array + */ +void Animation::setPrologueFrames(const int *frames, int count, int maxFrames) { + _prologueFrames.resize(count); + + for (int idx = 0; idx < count; ++idx, frames + maxFrames) { + _prologueFrames[idx].resize(maxFrames); + Common::copy(frames, frames + maxFrames, &_prologueFrames[idx][0]); + } +} + +/** + * Load the title name array + */ +void Animation::setTitleNames(const char *const *names, int count) { + for (int idx = 0; idx < count; ++idx, names++) { + _titleNames.push_back(*names); + } +} + +/** + * Load the title frame array + */ +void Animation::setTitleFrames(const int *frames, int count, int maxFrames) { + _titleFrames.resize(count); + + for (int idx = 0; idx < count; ++idx, frames + maxFrames) { + _titleFrames[idx].resize(maxFrames); + Common::copy(frames, frames + maxFrames, &_titleFrames[idx][0]); + } +} + /** * Checks for whether an animation is being played that has associated sound */ @@ -178,16 +187,16 @@ const int *Animation::checkForSoundFrames(const Common::String &filename) { const int *frames = &NO_FRAMES; if (_vm->_soundOverride.empty()) { - for (int idx = 0; idx < PROLOGUE_NAMES_COUNT; ++idx) { - if (filename.equalsIgnoreCase(PROLOGUE_NAMES[idx])) { - frames = &PROLOGUE_FRAMES[idx][0]; + for (Common::Array::size_type idx = 0; idx < _prologueNames.size(); ++idx) { + if (filename.equalsIgnoreCase(_prologueNames[idx])) { + frames = &_prologueFrames[idx][0]; break; } } } else { - for (int idx = 0; idx < TITLE_NAMES_COUNT; ++idx) { - if (filename.equalsIgnoreCase(TITLE_NAMES[idx])) { - frames = &TITLE_FRAMES[idx][0]; + for (Common::Array::size_type idx = 0; idx < _titleNames.size(); ++idx) { + if (filename.equalsIgnoreCase(_titleNames[idx])) { + frames = &_titleFrames[idx][0]; break; } } diff --git a/engines/sherlock/animation.h b/engines/sherlock/animation.h index 245d83789f..5802ffcd88 100644 --- a/engines/sherlock/animation.h +++ b/engines/sherlock/animation.h @@ -25,20 +25,35 @@ #include "common/scummsys.h" #include "common/str.h" +#include "common/array.h" namespace Sherlock { +#define FRAMES_END 32000 + class SherlockEngine; class Animation { private: SherlockEngine *_vm; + Common::Array _prologueNames; + Common::Array> _prologueFrames; + + Common::Array _titleNames; + Common::Array> _titleFrames; + const int *checkForSoundFrames(const Common::String &filename); public: public: Animation(SherlockEngine *vm); + void setPrologueNames(const char *const *names, int count); + void setPrologueFrames(const int *frames, int count, int maxFrames); + + void setTitleNames(const char *const *names, int count); + void setTitleFrames(const int *frames, int count, int maxFrames); + bool play(const Common::String &filename, int minDelay, int fade, bool setPalette, int speed); }; diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 8dc75c034f..5d84a7f5ed 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -22,11 +22,46 @@ #include "sherlock/scalpel/scalpel.h" #include "sherlock/sherlock.h" +#include "sherlock/animation.h" namespace Sherlock { namespace Scalpel { +#define PROLOGUE_NAMES_COUNT 6 + +// The following are a list of filenames played in the prologue that have +// special effects associated with them at specific frames +static const char *const PROLOGUE_NAMES[PROLOGUE_NAMES_COUNT] = { + "subway1", "subway2", "finale2", "suicid", "coff3", "coff4" +}; + +static const int PROLOGUE_FRAMES[6][9] = { + { 4, 26, 54, 72, 92, 134, FRAMES_END }, + { 2, 80, 95, 117, 166, FRAMES_END }, + { 1, FRAMES_END }, + { 42, FRAMES_END }, + { FRAMES_END }, + { FRAMES_END } +}; + +#define TITLE_NAMES_COUNT 7 + +// Title animations file list +static const char *const TITLE_NAMES[TITLE_NAMES_COUNT] = { + "27pro1", "14note", "coff1", "coff2", "coff3", "coff4", "14kick" +}; + +static const int TITLE_FRAMES[7][9] = { + { 29, 131, FRAMES_END }, + { 55, 80, 95, 117, 166, FRAMES_END }, + { 15, FRAMES_END }, + { 4, 37, 92, FRAMES_END }, + { 2, 43, FRAMES_END }, + { 2, FRAMES_END }, + { 10, 50, FRAMES_END } +}; + #define NUM_PLACES 100 const int MAP_X[NUM_PLACES] = { 0, 368, 0, 219, 0, 282, 0, 43, 0, 0, 396, 408, 0, 0, 0, 568, 37, 325, @@ -227,6 +262,12 @@ void ScalpelEngine::initialize() { // Set up constants used by the talk system _talk->setSequences(&TALK_SEQUENCES[0][0], &STILL_SEQUENCES[0][0], MAX_PEOPLE); + _animation->setPrologueNames(&PROLOGUE_NAMES[0], PROLOGUE_NAMES_COUNT); + _animation->setPrologueFrames(&PROLOGUE_FRAMES[0][0], 6, 9); + + _animation->setTitleNames(&TITLE_NAMES[0], TITLE_NAMES_COUNT); + _animation->setTitleFrames(&TITLE_FRAMES[0][0], 7, 9); + // Starting scene if (getIsDemo()) _scene->_goToScene = 3; -- cgit v1.2.3 From a0467ea60d7eac0839ff88f6fedf50007c7e48d1 Mon Sep 17 00:00:00 2001 From: sirlemonhead Date: Tue, 12 May 2015 00:53:49 +0100 Subject: SHERLOCK: Correct some minor spelling mistakes --- engines/sherlock/inventory.cpp | 4 ++-- engines/sherlock/talk.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index af2c4be0e4..d8c0104e6c 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -117,8 +117,8 @@ void Inventory::loadGraphics() { Common::fill(&_invShapes[0], &_invShapes[MAX_VISIBLE_INVENTORY], (ImageFile *)nullptr); for (int idx = _invIndex; (idx < _holdings) && (idx - _invIndex) < MAX_VISIBLE_INVENTORY; ++idx) { - // Get the name of the item to be dispalyed, figure out it's accompanying - // .VGS file with it's picture, and then load it + // Get the name of the item to be displayed, figure out its accompanying + // .VGS file with its picture, and then load it int invNum = findInv((*this)[idx]._name); Common::String fName = Common::String::format("item%02d.vgs", invNum + 1); diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index a1e124aa95..3520a02296 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -379,7 +379,7 @@ void Talk::talkTo(const Common::String &filename) { byte color = ui._endKeyActive ? COMMAND_FOREGROUND : COMMAND_NULL; - // If the window is alraedy open, simply draw. Otherwise, do it + // If the window is already open, simply draw. Otherwise, do it // to the back buffer and then summon the window if (ui._windowOpen) { screen.buttonPrint(Common::Point(119, CONTROLS_Y), color, true, "Exit"); -- cgit v1.2.3 From cf6276145b78e60d0cc3e20f12b78a16a8091c7d Mon Sep 17 00:00:00 2001 From: sirlemonhead Date: Tue, 12 May 2015 18:00:35 +0100 Subject: SHERLOCK: Fix to correctly increment animation variables --- engines/sherlock/animation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 5c11c4f6fb..de72de63f9 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -153,7 +153,7 @@ void Animation::setPrologueNames(const char *const *names, int count) { void Animation::setPrologueFrames(const int *frames, int count, int maxFrames) { _prologueFrames.resize(count); - for (int idx = 0; idx < count; ++idx, frames + maxFrames) { + for (int idx = 0; idx < count; ++idx, frames += maxFrames) { _prologueFrames[idx].resize(maxFrames); Common::copy(frames, frames + maxFrames, &_prologueFrames[idx][0]); } @@ -174,7 +174,7 @@ void Animation::setTitleNames(const char *const *names, int count) { void Animation::setTitleFrames(const int *frames, int count, int maxFrames) { _titleFrames.resize(count); - for (int idx = 0; idx < count; ++idx, frames + maxFrames) { + for (int idx = 0; idx < count; ++idx, frames += maxFrames) { _titleFrames[idx].resize(maxFrames); Common::copy(frames, frames + maxFrames, &_titleFrames[idx][0]); } -- cgit v1.2.3 From 3a74cb7b57e09e9826c6534c5d53a53753045524 Mon Sep 17 00:00:00 2001 From: sirlemonhead Date: Tue, 12 May 2015 18:17:05 +0100 Subject: SHERLOCK: Fix GCC compilation with correct whitespace for nested Common:Array --- engines/sherlock/animation.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/animation.h b/engines/sherlock/animation.h index 5802ffcd88..06614df6b1 100644 --- a/engines/sherlock/animation.h +++ b/engines/sherlock/animation.h @@ -38,10 +38,10 @@ private: SherlockEngine *_vm; Common::Array _prologueNames; - Common::Array> _prologueFrames; + Common::Array > _prologueFrames; Common::Array _titleNames; - Common::Array> _titleFrames; + Common::Array > _titleFrames; const int *checkForSoundFrames(const Common::String &filename); public: -- cgit v1.2.3 From 72c9b9f56b99ca9c286de8618be4f473c0969983 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Tue, 12 May 2015 21:34:45 +0200 Subject: SHERLOCK: Implement sound priority --- engines/sherlock/animation.cpp | 2 +- engines/sherlock/objects.cpp | 2 +- engines/sherlock/scene.cpp | 9 ++------ engines/sherlock/sound.cpp | 41 +++++++++++++++---------------------- engines/sherlock/sound.h | 9 ++++---- engines/sherlock/talk.cpp | 2 +- engines/sherlock/user_interface.cpp | 2 +- 7 files changed, 26 insertions(+), 41 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index de72de63f9..a8edf77532 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -111,7 +111,7 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade, Common::String::format("%s%02d", filename.c_str(), soundNumber); if (sound._voices) - sound.playSound(fname); + sound.playSound(fname, WAIT_RETURN_IMMEDIATELY); } events.wait(speed); diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index ca8ba1759a..acb13dd593 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -613,7 +613,7 @@ void Object::checkObject() { if (sound._soundOn && !_countCAnimFrames) { if (!scene._sounds[v - 1]._name.empty() && sound._digitized) - sound.playLoadedSound(v - 1, 0); + sound.playLoadedSound(v - 1, WAIT_RETURN_IMMEDIATELY); } } else if (v >= FLIP_CODE && v <= (FLIP_CODE + 2)) { // Flip code diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index ca9f19582c..4b0cbee07d 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -378,13 +378,8 @@ bool Scene::loadScene(const Common::String &filename) { for (int idx = 0; idx < numSounds; ++idx) _sounds[idx].synchronize(*rrmStream); - // If sound is turned on, load the sounds into memory - if (sound._soundOn) { - for (int idx = 0; idx < numSounds; ++idx) { - sound.loadSound(_sounds[idx]._name, _sounds[idx]._priority); - _sounds[idx]._name = ""; - } - } + for (int idx = 0; idx < numSounds; ++idx) + sound.loadSound(_sounds[idx]._name, _sounds[idx]._priority); // Read in palette rrmStream->read(screen._cMap, PALETTE_SIZE); diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index 51563d17a6..09e55ec82b 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -38,6 +38,7 @@ Sound::Sound(SherlockEngine *vm, Audio::Mixer *mixer): _vm(vm), _mixer(mixer) { _diskSoundPlaying = false; _soundPlaying = false; _soundIsOn = &_soundPlaying; + _curPriority = 0; _soundOn = true; _musicOn = true; @@ -57,8 +58,7 @@ void Sound::syncSoundSettings() { } void Sound::loadSound(const Common::String &name, int priority) { - // TODO - warning("TODO: Sound::loadSound"); + // No implementation required in ScummVM } char Sound::decodeSample(char sample, byte& prediction, int& step) { @@ -86,8 +86,8 @@ char Sound::decodeSample(char sample, byte& prediction, int& step) { return prediction; } -bool Sound::playSound(const Common::String &name, WaitType waitType) { - _mixer->stopHandle(_effectsHandle); +bool Sound::playSound(const Common::String &name, WaitType waitType, int priority) { + stopSound(); Common::String filename = name; if (!filename.contains('.')) @@ -103,7 +103,7 @@ bool Sound::playSound(const Common::String &name, WaitType waitType) { byte *decoded = (byte *)malloc((size - 1) * 2); - // +127 to eliminate the pop when the sound starts (signed vs unsignded PCM). Still does not help with the pop at the end + // +127 to eliminate the pop when the sound starts (signed vs unsigned PCM). Still does not help with the pop at the end byte prediction = (ptr[0] & 0x0f) + 127; int step = 0; int counter = 0; @@ -118,6 +118,7 @@ bool Sound::playSound(const Common::String &name, WaitType waitType) { Audio::AudioStream *audioStream = Audio::makeRawStream(decoded, (size - 2) * 2, rate, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES); _mixer->playStream(Audio::Mixer::kPlainSoundType, &_effectsHandle, audioStream, -1, Audio::Mixer::kMaxChannelVolume); _soundPlaying = true; + _curPriority = priority; if (waitType == WAIT_RETURN_IMMEDIATELY) { _diskSoundPlaying = true; @@ -148,34 +149,24 @@ bool Sound::playSound(const Common::String &name, WaitType waitType) { return retval; } -void Sound::cacheSound(const Common::String &name, int index) { - // TODO - warning("TODO: Sound::cacheSound"); -} +void Sound::playLoadedSound(int bufNum, WaitType waitType) { + if (_mixer->isSoundHandleActive(_effectsHandle) && (_curPriority > _vm->_scene->_sounds[bufNum]._priority)) + return; -void Sound::playLoadedSound(int bufNum, int waitMode) { - // TODO - warning("TODO: Sound::playLoadedSound"); -} + stopSound(); + playSound(_vm->_scene->_sounds[bufNum]._name, waitType, _vm->_scene->_sounds[bufNum]._priority); -void Sound::playCachedSound(int index) { - // TODO - warning("TODO: Sound::playCachedSound"); + return; } void Sound::freeLoadedSounds() { - // TODO - warning("TODO: Sound::clearLoadedSound"); -} - -void Sound::clearCache() { - // TODO - warning("TODO: Sound::clearCache"); + // As sounds are played with DisposeAfterUse::YES, stopping the sounds also + // frees them + stopSound(); } void Sound::stopSound() { - // TODO - warning("TODO: Sound::stopSound"); + _mixer->stopHandle(_effectsHandle); } void Sound::playMusic(const Common::String &name) { diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index 213a6f7a1e..659df57bc3 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -44,6 +44,7 @@ private: SherlockEngine *_vm; Audio::Mixer *_mixer; Audio::SoundHandle _effectsHandle; + int _curPriority; char decodeSample(char sample, byte& prediction, int& step); public: @@ -63,13 +64,11 @@ public: void syncSoundSettings(); void loadSound(const Common::String &name, int priority); - bool playSound(const Common::String &name, WaitType waitType = WAIT_RETURN_IMMEDIATELY); - void cacheSound(const Common::String &name, int index); - void playLoadedSound(int bufNum, int waitMode); - void playCachedSound(int index); + bool playSound(const Common::String &name, WaitType waitType, int priority = 100); + void playLoadedSound(int bufNum, WaitType waitType); void freeLoadedSounds(); - void clearCache(); void stopSound(); + int loadSong(int songNumber); void startSong(); void freeSong(); diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 3520a02296..61f0004fd6 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1278,7 +1278,7 @@ void Talk::doScript(const Common::String &script) { if (sound._voices) { for (int idx = 0; idx < 8 && str[idx] != '~'; ++idx) tempString += str[idx]; - sound.playSound(tempString); + sound.playSound(tempString, WAIT_RETURN_IMMEDIATELY); // Set voices to wait for more sound._voices = 2; diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 8b3ee426a4..d65bd9c01d 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1683,7 +1683,7 @@ void UserInterface::doTalkControl() { people.setTalking(0); if (!talk._statements[_selector]._voiceFile.empty() && sound._voices) { - sound.playSound(talk._statements[_selector]._voiceFile); + sound.playSound(talk._statements[_selector]._voiceFile, WAIT_RETURN_IMMEDIATELY); // Set voices as an indicator for waiting sound._voices = 2; -- cgit v1.2.3 From 2824c8214a86927cd3532cc07b7bc7dedcab74a1 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 12 May 2015 19:14:39 -0400 Subject: SHERLOCK: Fix buffer reference in randomTransition --- engines/sherlock/screen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 2713d192e7..c236915992 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -234,7 +234,7 @@ void Screen::randomTransition() { } // Make sure everything has been transferred - blitFrom(_backBuffer1); + blitFrom(*_backBuffer); } /** -- cgit v1.2.3 From f12fe46fad425ca451036f6af06beab5ec3a81c5 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 12 May 2015 19:19:49 -0400 Subject: SHERLOCK: Remove redundant check from mergeDirtyRects --- engines/sherlock/screen.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index c236915992..fb155bf502 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -170,13 +170,6 @@ void Screen::addDirtyRect(const Common::Rect &r) { void Screen::mergeDirtyRects() { Common::List::iterator rOuter, rInner; - // Ensure dirty rect list has at least two entries - rOuter = _dirtyRects.begin(); - for (int i = 0; i < 2; ++i, ++rOuter) { - if (rOuter == _dirtyRects.end()) - return; - } - // Process the dirty rect list to find any rects to merge for (rOuter = _dirtyRects.begin(); rOuter != _dirtyRects.end(); ++rOuter) { rInner = rOuter; -- cgit v1.2.3 From 95212c5f0290b2cbebed6b179efa57397f08b39b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 12 May 2015 19:50:16 -0400 Subject: SHERLOCK: Whitespace fixes --- engines/sherlock/graphics.h | 2 +- engines/sherlock/people.h | 10 +++++----- engines/sherlock/resources.cpp | 28 ++++++++++++++-------------- engines/sherlock/scalpel/scalpel.cpp | 2 +- engines/sherlock/scene.h | 4 ++-- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index 91a65c8c43..d4a1584968 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -37,7 +37,7 @@ private: protected: virtual void addDirtyRect(const Common::Rect &r) {} public: - Surface(uint16 width, uint16 height); + Surface(uint16 width, uint16 height); Surface(); virtual ~Surface(); diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index ee16fab243..f98c3db867 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -32,11 +32,11 @@ namespace Sherlock { // People definitions enum PeopleId { - PLAYER = 0, - AL = 0, - PEG = 1, - NUM_OF_PEOPLE = 2, // Holmes and Watson - MAX_PEOPLE = 66 // Total of all NPCs + PLAYER = 0, + AL = 0, + PEG = 1, + NUM_OF_PEOPLE = 2, // Holmes and Watson + MAX_PEOPLE = 66 // Total of all NPCs }; // Animation sequence identifiers for characters diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index 3f74590386..f50f780195 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -294,7 +294,7 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette, bool loadPalette(stream); int streamSize = stream.size(); - while (stream.pos() < streamSize) { + while (stream.pos() < streamSize) { ImageFrame frame; frame._width = stream.readUint16LE() + 1; frame._height = stream.readUint16LE() + 1; @@ -309,30 +309,30 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette, bool frame._rleEncoded = stream.readByte() == 1; frame._offset.x = stream.readByte(); } - frame._offset.y = stream.readByte(); + frame._offset.y = stream.readByte(); frame._rleEncoded = !skipPalette && frame._rleEncoded; if (frame._paletteBase) { // Nibble packed frame data frame._size = (frame._width * frame._height) / 2; } else if (frame._rleEncoded) { - // this size includes the header size, which we subtract + // This size includes the header size, which we subtract frame._size = stream.readUint16LE() - 11; frame._rleMarker = stream.readByte(); - } else { + } else { // Uncompressed data frame._size = frame._width * frame._height; - } + } // Load data for frame and decompress it byte *data = new byte[frame._size]; stream.read(data, frame._size); - decompressFrame(frame, data); + decompressFrame(frame, data); delete[] data; push_back(frame); - } + } } /** @@ -372,17 +372,17 @@ void ImageFile::decompressFrame(ImageFrame &frame, const byte *src) { } } else if (frame._rleEncoded) { // RLE encoded - byte *dst = (byte *)frame._frame.getPixels(); + byte *dst = (byte *)frame._frame.getPixels(); int frameSize = frame._width * frame._height; while (frameSize > 0) { if (*src == frame._rleMarker) { - byte rleColor = src[1]; - byte rleCount = src[2]; - src += 3; - frameSize -= rleCount; - while (rleCount--) - *dst++ = rleColor; + byte rleColor = src[1]; + byte rleCount = src[2]; + src += 3; + frameSize -= rleCount; + while (rleCount--) + *dst++ = rleColor; } else { *dst++ = *src++; --frameSize; diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 5d84a7f5ed..6959e435d2 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -81,7 +81,7 @@ const int MAP_TRANSLATE[NUM_PLACES] = { }; const byte MAP_SEQUENCES[3][MAX_FRAME] = { - { 1, 1, 2, 3, 4, 0 }, // Overview Still + { 1, 1, 2, 3, 4, 0 }, // Overview Still { 5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 0 }, { 5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 0 } }; diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 8ef5d74785..96714c4a3a 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -33,8 +33,8 @@ namespace Sherlock { #define SCENES_COUNT 63 -#define MAX_ZONES 40 -#define INFO_LINE 140 +#define MAX_ZONES 40 +#define INFO_LINE 140 class SherlockEngine; -- cgit v1.2.3 From 2db576357f1a697d0a03e9fc32de6604bdf138ef Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 12 May 2015 19:55:53 -0400 Subject: SHERLOCK: Rename object loading methods from synchronize to load --- engines/sherlock/objects.cpp | 24 ++++++++++++------------ engines/sherlock/objects.h | 8 ++++---- engines/sherlock/scene.cpp | 4 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index acb13dd593..b4371cd71b 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -365,9 +365,9 @@ void Sprite::checkSprite() { /*----------------------------------------------------------------*/ /** - * Synchronize the data for a savegame + * Load the data for the action */ -void ActionType::synchronize(Common::SeekableReadStream &s) { +void ActionType::load(Common::SeekableReadStream &s) { char buffer[12]; _cAnimNum = s.readByte(); @@ -391,9 +391,9 @@ UseType::UseType() { } /** - * Synchronize the data for a savegame + * Load the data for the UseType */ -void UseType::synchronize(Common::SeekableReadStream &s) { +void UseType::load(Common::SeekableReadStream &s) { char buffer[12]; _cAnimNum = s.readByte(); @@ -459,9 +459,9 @@ Object::Object() { } /** - * Load the object data from the passed stream + * Load the data for the object */ -void Object::synchronize(Common::SeekableReadStream &s) { +void Object::load(Common::SeekableReadStream &s) { char buffer[41]; s.read(buffer, 12); _name = Common::String(buffer); @@ -504,7 +504,7 @@ void Object::synchronize(Common::SeekableReadStream &s) { _misc = s.readByte(); _maxFrames = s.readUint16LE(); _flags = s.readByte(); - _aOpen.synchronize(s); + _aOpen.load(s); _aType = (AType)s.readByte(); _lookFrames = s.readByte(); _seqCounter = s.readByte(); @@ -512,18 +512,18 @@ void Object::synchronize(Common::SeekableReadStream &s) { _lookPosition.y = s.readByte(); _lookFacing = s.readByte(); _lookcAnim = s.readByte(); - _aClose.synchronize(s); + _aClose.load(s); _seqStack = s.readByte(); _seqTo = s.readByte(); _descOffset = s.readUint16LE(); _seqCounter2 = s.readByte(); _seqSize = s.readUint16LE(); s.skip(1); - _aMove.synchronize(s); + _aMove.load(s); s.skip(8); for (int idx = 0; idx < 4; ++idx) - _use[idx].synchronize(s); + _use[idx].load(s); } /** @@ -1099,9 +1099,9 @@ const Common::Rect Object::getOldBounds() const { /*----------------------------------------------------------------*/ /** - * Synchronize the data for a savegame + * Load the data for the animation */ -void CAnim::synchronize(Common::SeekableReadStream &s) { +void CAnim::load(Common::SeekableReadStream &s) { char buffer[12]; s.read(buffer, 12); _name = Common::String(buffer); diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 52bd15cbbc..4068973e58 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -148,7 +148,7 @@ struct ActionType { int _cAnimSpeed; Common::String _names[4]; - void synchronize(Common::SeekableReadStream &s); + void load(Common::SeekableReadStream &s); }; struct UseType { @@ -161,7 +161,7 @@ struct UseType { Common::String _target; UseType(); - void synchronize(Common::SeekableReadStream &s); + void load(Common::SeekableReadStream &s); }; class Object { @@ -222,7 +222,7 @@ public: Object(); - void synchronize(Common::SeekableReadStream &s); + void load(Common::SeekableReadStream &s); void toggleHidden(); @@ -255,7 +255,7 @@ struct CAnim { Common::Point _teleportPos; // Location Holmes shoul teleport to after int _teleportDir; // playing canim - void synchronize(Common::SeekableReadStream &s); + void load(Common::SeekableReadStream &s); }; struct SceneImage { diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 4b0cbee07d..f473004d9a 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -261,7 +261,7 @@ bool Scene::loadScene(const Common::String &filename) { _bgShapes.resize(bgHeader._numStructs); for (int idx = 0; idx < bgHeader._numStructs; ++idx) - _bgShapes[idx].synchronize(*infoStream); + _bgShapes[idx].load(*infoStream); if (bgHeader._descSize) { _descText.resize(bgHeader._descSize); @@ -318,7 +318,7 @@ bool Scene::loadScene(const Common::String &filename) { _cAnim.resize(bgHeader._numcAnimations); for (uint idx = 0; idx < _cAnim.size(); ++idx) - _cAnim[idx].synchronize(*canimStream); + _cAnim[idx].load(*canimStream); delete canimStream; } -- cgit v1.2.3 From 0af230e9489df34d54f0ecdee062827b52182020 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 12 May 2015 20:40:47 -0400 Subject: SHERLOCK: Fix speed of animations --- engines/sherlock/animation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index a8edf77532..1d6c12f668 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -114,7 +114,7 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade, sound.playSound(fname, WAIT_RETURN_IMMEDIATELY); } - events.wait(speed); + events.wait(speed * 3); } if (events.kbHit()) { -- cgit v1.2.3 From 44fbef5498070ee12fddb42c067d943e56d22f0e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 12 May 2015 21:01:57 -0400 Subject: SHERLOCK: Add missing setting of _oldSelector --- engines/sherlock/user_interface.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index d65bd9c01d..41505b89fc 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1612,6 +1612,8 @@ void UserInterface::doTalkControl() { if (_selector != -1) talk.talkLine(_selector, talk._statements[_selector]._talkMap, TALK_FOREGROUND, talk._statements[_selector]._talkPos.top, true); + + _oldSelector = _selector; } if (events._released || _keyboardInput) { -- cgit v1.2.3 From c1244623e084ab230aba3ad8cefb238f98575805 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 12 May 2015 22:06:39 -0400 Subject: SHERLOCK: More rename of synchronize methods to load --- engines/sherlock/scene.cpp | 38 ++++++++++++++++++++++++++++---------- engines/sherlock/scene.h | 10 +++++----- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index f473004d9a..093c305a97 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -27,7 +27,10 @@ namespace Sherlock { -void BgFileHeader::synchronize(Common::SeekableReadStream &s) { +/** + * Load the data for the object + */ +void BgFileHeader::load(Common::SeekableReadStream &s) { _numStructs = s.readUint16LE(); _numImages = s.readUint16LE(); _numcAnimations = s.readUint16LE(); @@ -38,7 +41,10 @@ void BgFileHeader::synchronize(Common::SeekableReadStream &s) { /*----------------------------------------------------------------*/ -void BgfileheaderInfo::synchronize(Common::SeekableReadStream &s) { +/** + * Load the data for the object + */ +void BgfileheaderInfo::load(Common::SeekableReadStream &s) { _filesize = s.readUint32LE(); _maxFrames = s.readByte(); @@ -49,7 +55,10 @@ void BgfileheaderInfo::synchronize(Common::SeekableReadStream &s) { /*----------------------------------------------------------------*/ -void Exit::synchronize(Common::SeekableReadStream &s) { +/** + * Load the data for the object + */ +void Exit::load(Common::SeekableReadStream &s) { int xp = s.readSint16LE(); int yp = s.readSint16LE(); int xSize = s.readSint16LE(); @@ -65,14 +74,20 @@ void Exit::synchronize(Common::SeekableReadStream &s) { /*----------------------------------------------------------------*/ -void SceneEntry::synchronize(Common::SeekableReadStream &s) { +/** + * Load the data for the object + */ +void SceneEntry::load(Common::SeekableReadStream &s) { _startPosition.x = s.readSint16LE(); _startPosition.y = s.readSint16LE(); _startDir = s.readByte(); _allow = s.readByte(); } -void SceneSound::synchronize(Common::SeekableReadStream &s) { +/** + * Load the data for the object + */ +void SceneSound::load(Common::SeekableReadStream &s) { char buffer[9]; s.read(buffer, 8); buffer[8] = '\0'; @@ -83,6 +98,9 @@ void SceneSound::synchronize(Common::SeekableReadStream &s) { /*----------------------------------------------------------------*/ +/** + * Retuurn the index of the passed object in the array + */ int ObjectArray::indexOf(const Object &obj) const { for (uint idx = 0; idx < size(); ++idx) { if (&(*this)[idx] == &obj) @@ -244,7 +262,7 @@ bool Scene::loadScene(const Common::String &filename) { // Go to header and read it in rrmStream->seek(rrmStream->readUint32LE()); BgFileHeader bgHeader; - bgHeader.synchronize(*rrmStream); + bgHeader.load(*rrmStream); _invGraphicItems = bgHeader._numImages + 1; // Read in the shapes header info @@ -252,7 +270,7 @@ bool Scene::loadScene(const Common::String &filename) { bgInfo.resize(bgHeader._numStructs); for (uint idx = 0; idx < bgInfo.size(); ++idx) - bgInfo[idx].synchronize(*rrmStream); + bgInfo[idx].load(*rrmStream); // Read information Common::SeekableReadStream *infoStream = !_lzwMode ? rrmStream : @@ -366,17 +384,17 @@ bool Scene::loadScene(const Common::String &filename) { _exits.resize(numExits); for (int idx = 0; idx < numExits; ++idx) - _exits[idx].synchronize(*rrmStream); + _exits[idx].load(*rrmStream); // Read in the entrance - _entrance.synchronize(*rrmStream); + _entrance.load(*rrmStream); // Initialize sound list int numSounds = rrmStream->readByte(); _sounds.resize(numSounds); for (int idx = 0; idx < numSounds; ++idx) - _sounds[idx].synchronize(*rrmStream); + _sounds[idx].load(*rrmStream); for (int idx = 0; idx < numSounds; ++idx) sound.loadSound(_sounds[idx]._name, _sounds[idx]._priority); diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 96714c4a3a..665f5d28e4 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -46,7 +46,7 @@ struct BgFileHeader { int _seqSize; int _fill; - void synchronize(Common::SeekableReadStream &s); + void load(Common::SeekableReadStream &s); }; struct BgfileheaderInfo { @@ -54,7 +54,7 @@ struct BgfileheaderInfo { int _maxFrames; // How many unique frames in object Common::String _filename; // Filename of object - void synchronize(Common::SeekableReadStream &s); + void load(Common::SeekableReadStream &s); }; struct Exit { @@ -65,7 +65,7 @@ struct Exit { Common::Point _people; int _peopleDir; - void synchronize(Common::SeekableReadStream &s); + void load(Common::SeekableReadStream &s); }; struct SceneEntry { @@ -73,14 +73,14 @@ struct SceneEntry { int _startDir; int _allow; - void synchronize(Common::SeekableReadStream &s); + void load(Common::SeekableReadStream &s); }; struct SceneSound { Common::String _name; int _priority; - void synchronize(Common::SeekableReadStream &s); + void load(Common::SeekableReadStream &s); }; class ObjectArray: public Common::Array { -- cgit v1.2.3 From 187b5838533b0a182b8b44c4bfd513eeaae6aaa0 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Wed, 13 May 2015 08:24:48 +0200 Subject: SHERLOCK: Handle multiple sound containers --- engines/sherlock/sound.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index 09e55ec82b..7b8d6c69c6 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -45,6 +45,8 @@ Sound::Sound(SherlockEngine *vm, Audio::Mixer *mixer): _vm(vm), _mixer(mixer) { _speechOn = true; _vm->_res->addToCache("MUSIC.LIB"); + _vm->_res->addToCache("TITLE.SND"); + _vm->_res->addToCache("EPILOGUE.SND"); _vm->_res->addToCache("SND.SND"); } @@ -92,7 +94,18 @@ bool Sound::playSound(const Common::String &name, WaitType waitType, int priorit Common::String filename = name; if (!filename.contains('.')) filename += ".SND"; - Common::SeekableReadStream *stream = _vm->_res->load(filename, "TITLE.SND"); + + Common::SeekableReadStream *stream = nullptr; + + if (_vm->_res->exists(filename)) + stream = _vm->_res->load(filename, "TITLE.SND"); + else if (_vm->_res->exists(filename)) + stream = _vm->_res->load(filename, "EPILOGUE.SND"); + else if (_vm->_res->exists(filename)) + stream = _vm->_res->load(filename, "SND.SND"); + + if (!stream) + error("Unable to find sound file %s", filename.c_str()); stream->skip(2); int size = stream->readUint32BE(); -- cgit v1.2.3 From c6c056133c7720fc83de0513acbf4b0cc96bc50e Mon Sep 17 00:00:00 2001 From: Strangerke Date: Wed, 13 May 2015 22:54:03 +0200 Subject: SHERLOCK: Remove useless checks in playSound --- engines/sherlock/sound.cpp | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index 7b8d6c69c6..59098c32cc 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -95,17 +95,10 @@ bool Sound::playSound(const Common::String &name, WaitType waitType, int priorit if (!filename.contains('.')) filename += ".SND"; - Common::SeekableReadStream *stream = nullptr; - - if (_vm->_res->exists(filename)) - stream = _vm->_res->load(filename, "TITLE.SND"); - else if (_vm->_res->exists(filename)) - stream = _vm->_res->load(filename, "EPILOGUE.SND"); - else if (_vm->_res->exists(filename)) - stream = _vm->_res->load(filename, "SND.SND"); + Common::SeekableReadStream *stream = _vm->_res->load(filename); if (!stream) - error("Unable to find sound file %s", filename.c_str()); + error("Unable to find sound file '%s'", filename.c_str()); stream->skip(2); int size = stream->readUint32BE(); @@ -128,6 +121,15 @@ bool Sound::playSound(const Common::String &name, WaitType waitType, int priorit free(data); +#if 0 + // Debug : used to dump files + Common::DumpFile outFile; + outFile.open(filename); + outFile.write(decoded, (size - 2) * 2); + outFile.flush(); + outFile.close(); +#endif + Audio::AudioStream *audioStream = Audio::makeRawStream(decoded, (size - 2) * 2, rate, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES); _mixer->playStream(Audio::Mixer::kPlainSoundType, &_effectsHandle, audioStream, -1, Audio::Mixer::kMaxChannelVolume); _soundPlaying = true; @@ -151,14 +153,6 @@ bool Sound::playSound(const Common::String &name, WaitType waitType, int priorit _soundPlaying = false; _mixer->stopHandle(_effectsHandle); -#if 0 - // Debug : used to dump files - Common::DumpFile outFile; - outFile.open(filename); - outFile.write(decoded, (size - 2) * 2); - outFile.flush(); - outFile.close(); -#endif return retval; } -- cgit v1.2.3 From 6f263e5774f7f4f8877932bb136621ac9606d11e Mon Sep 17 00:00:00 2001 From: Strangerke Date: Wed, 13 May 2015 22:54:57 +0200 Subject: SHERLOCK: Fix a glitch in decompressLZ, when file size is unknown --- engines/sherlock/decompress.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/decompress.cpp b/engines/sherlock/decompress.cpp index dfa573209f..b781285471 100644 --- a/engines/sherlock/decompress.cpp +++ b/engines/sherlock/decompress.cpp @@ -32,7 +32,7 @@ namespace Sherlock { */ Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source, int32 outSize) { if (outSize == -1) { - source.seek(5); + source.seek(4); outSize = source.readSint32LE(); } -- cgit v1.2.3 From fab0e75c292887254493f0efc6a5a40c851aba53 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Wed, 13 May 2015 22:57:15 +0200 Subject: SHERLOCK: Rework a bit Cache::load to use MKTAG, add support for compressed sub-files in Resources::load --- engines/sherlock/resources.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index f50f780195..e990013cb3 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -66,18 +66,15 @@ void Cache::load(const Common::String &name, Common::SeekableReadStream &stream) if (_resources.contains(name)) return; - // Check whether the file is compressed - const char LZW_HEADER[5] = { "LZV\x1a" }; - char header[5]; - stream.read(header, 5); - bool isCompressed = !strncmp(header, LZW_HEADER, 5); + int32 signature = stream.readUint32BE(); stream.seek(0); // Allocate a new cache entry _resources[name] = CacheEntry(); CacheEntry &cacheEntry = _resources[name]; - if (isCompressed) { + // Check whether the file is compressed + if (signature == MKTAG('L', 'Z', 'V', 26)) { // It's compressed, so decompress the file and store it's data in the cache entry Common::SeekableReadStream *decompressed = decompressLZ(stream); cacheEntry.resize(decompressed->size()); @@ -168,8 +165,19 @@ Common::SeekableReadStream *Resources::load(const Common::String &filename) { stream->seek(entry._offset); Common::SeekableReadStream *resStream = stream->readStream(entry._size); - delete stream; - return resStream; + // Check whether the file is compressed + if (resStream->readUint32BE() == MKTAG('L', 'Z', 'V', 26)) { + resStream->seek(0); + // It's compressed, so decompress the sub-file and return it + Common::SeekableReadStream *decompressed = decompressLZ(*resStream); + delete stream; + delete resStream; + return decompressed; + } else { + resStream->seek(0); + delete stream; + return resStream; + } } } -- cgit v1.2.3 From 4cffb1c65fe9a1d8665d3303be8cb6f3acc1494d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 13 May 2015 18:08:06 -0400 Subject: SHERLOCK: Simplify rect check in addDirtyRect --- engines/sherlock/screen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index fb155bf502..4cc3ba92e7 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -161,7 +161,7 @@ void Screen::fadeIn(const byte palette[PALETTE_SIZE], int speed) { */ void Screen::addDirtyRect(const Common::Rect &r) { _dirtyRects.push_back(r); - assert(r.isValidRect() && r.width() > 0 && r.height() > 0); + assert(r.width() > 0 && r.height() > 0); } /** -- cgit v1.2.3 From 2a7019bd3d47c9e40b5e78ee83cc7bfb1c08bd1a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 13 May 2015 18:33:23 -0400 Subject: SHERLOCK: Remove redundant _scriptCurrentIndex field --- engines/sherlock/talk.cpp | 40 ++++--------------------------------- engines/sherlock/talk.h | 1 - engines/sherlock/user_interface.cpp | 3 --- 3 files changed, 4 insertions(+), 40 deletions(-) diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 61f0004fd6..d656431823 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -104,7 +104,6 @@ Talk::Talk(SherlockEngine *vm): _vm(vm) { _moreTalkDown = _moreTalkUp = false; _scriptMoreFlag = 0; _scriptSaveIndex = -1; - _scriptCurrentIndex = -1; } /** @@ -1082,10 +1081,6 @@ void Talk::doScript(const Common::String &script) { // Handle control code switch (c) { case SWITCH_SPEAKER: - // Save the current point in the script, since it might be intterupted by - // doing bg anims in the next call, so we need to know where to return to - _scriptCurrentIndex = str - scriptStart; - if (!(_speaker & 128)) people.clearTalking(); if (_talkToAbort) @@ -1103,10 +1098,7 @@ void Talk::doScript(const Common::String &script) { break; case RUN_CANIMATION: - // Save the current point in the script, since it might be intterupted by - // doing bg anims in the next call, so we need to know where to return to ++str; - _scriptCurrentIndex = (str + 1) - scriptStart; scene.startCAnim((str[0] - 1) & 127, (str[0] & 128) ? -1 : 1); if (_talkToAbort) return; @@ -1143,10 +1135,6 @@ void Talk::doScript(const Common::String &script) { break; case REMOVE_PORTRAIT: - // Save the current point in the script, since it might be intterupted by - // doing bg anims in the next call, so we need to know where to return to - _scriptCurrentIndex = str - scriptStart; - if (_speaker >= 0 && _speaker < 128) people.clearTalking(); pullSequence(); @@ -1203,10 +1191,7 @@ void Talk::doScript(const Common::String &script) { } case WALK_TO_COORDS: - // Save the current point in the script, since it might be interrupted by - // doing bg anims in the next call, so we need to know where to return to ++str; - _scriptCurrentIndex = str - scriptStart; people.walkToCoords(Common::Point(((str[0] - 1) * 256 + str[1] - 1) * 100, str[2] * 100), str[3] - 1); @@ -1217,10 +1202,7 @@ void Talk::doScript(const Common::String &script) { break; case PAUSE_WITHOUT_CONTROL: - // Save the current point in the script, since it might be intterupted by - // doing bg anims in the next call, so we need to know where to return to ++str; - _scriptCurrentIndex = str - scriptStart; for (int idx = 0; idx < (str[0] - 1); ++idx) { scene.doBgAnim(); @@ -1234,10 +1216,6 @@ void Talk::doScript(const Common::String &script) { break; case BANISH_WINDOW: - // Save the current point in the script, since it might be intterupted by - // doing bg anims in the next call, so we need to know where to return to - _scriptCurrentIndex = str - scriptStart; - if (!(_speaker & 128)) people.clearTalking(); pullSequence(); @@ -1403,19 +1381,19 @@ void Talk::doScript(const Common::String &script) { break; } - case CALL_TALK_FILE: + case CALL_TALK_FILE: { ++str; for (int idx = 0; idx < 8 && str[idx] != '~'; ++idx) tempString += str[idx]; str += 8; - _scriptCurrentIndex = str - scriptStart; + int scriptCurrentIndex = str - scriptStart; // Save the current script position and new talk file if (_scriptStack.size() < 9) { ScriptStackEntry rec1; rec1._name = _scriptName; - rec1._currentIndex = _scriptCurrentIndex; + rec1._currentIndex = scriptCurrentIndex; rec1._select = _scriptSelect; _scriptStack.push(rec1); @@ -1433,12 +1411,10 @@ void Talk::doScript(const Common::String &script) { endStr = true; wait = 0; break; + } case MOVE_MOUSE: - // Save the current point in the script, since it might be intterupted by - // doing bg anims in the next call, so we need to know where to return to ++str; - _scriptCurrentIndex = str - scriptStart; events.moveMouse(Common::Point((str[0] - 1) * 256 + str[1] - 1, str[2])); if (_talkToAbort) return; @@ -1464,10 +1440,6 @@ void Talk::doScript(const Common::String &script) { ++str; CAnim &animation = scene._cAnim[str[0] - 1]; - // Save the current point in the script, since it might be interrupted by - // doing bg anims in the next call, so we need to know where to return to - _scriptCurrentIndex = (str + 1) - scriptStart; - people.walkToCoords(animation._goto, animation._gotoDir); if (_talkToAbort) return; @@ -1614,10 +1586,6 @@ void Talk::doScript(const Common::String &script) { } if (wait) { - // Save the current point in the script, since it might be intterupted by - // doing bg anims in the next call, so we need to know where to return to - _scriptCurrentIndex = str - scriptStart; - // Handling pausing if (!pauseFlag && charCount < 160) charCount = 160; diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index d81586228f..b1a735827c 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -140,7 +140,6 @@ private: int _talkStealth; int _talkToFlag; int _scriptSaveIndex; - int _scriptCurrentIndex; private: void stripVoiceCommands(); void setTalkMap(); diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 41505b89fc..e4230cae83 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1694,9 +1694,6 @@ void UserInterface::doTalkControl() { sound._speechOn = false; } - // Set the _scriptCurrentIndex so if the statement is irrupted, the entire - // reply will be shown when it's restarted - talk._scriptCurrentIndex = 0; talk.waitForMore(talk._statements[_selector]._statement.size()); if (talk._talkToAbort) return; -- cgit v1.2.3 From afa49212e8dab03a48ec50c900a942c2843bce07 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 13 May 2015 19:00:52 -0400 Subject: SHERLOCK: Remove space/Enter handling for keyboard cursor We don't implement the keyboard cursor movement anyway, and it was stopping Space and Enter from working when showing dialogs --- engines/sherlock/user_interface.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index e4230cae83..aa6bf2ba81 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -167,11 +167,6 @@ void UserInterface::handleInput() { _vm->quitGame(); events.pollEvents(); return; - } else if (keyState.keycode == Common::KEYCODE_SPACE || - keyState.keycode == Common::KEYCODE_RETURN) { - events._pressed = false; - events._oldButtons = 0; - _keycode = Common::KEYCODE_INVALID; } } -- cgit v1.2.3 From 24b93a14be56725d65983082592029ee6d24f3c1 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 13 May 2015 20:05:19 -0400 Subject: SHERLOCK: Renamed graphics.cpp to surface.cpp --- engines/sherlock/graphics.cpp | 197 -------------------------------------- engines/sherlock/graphics.h | 60 ------------ engines/sherlock/map.h | 2 +- engines/sherlock/module.mk | 2 +- engines/sherlock/saveload.cpp | 2 +- engines/sherlock/screen.h | 3 +- engines/sherlock/sherlock.cpp | 2 +- engines/sherlock/surface.cpp | 197 ++++++++++++++++++++++++++++++++++++++ engines/sherlock/surface.h | 60 ++++++++++++ engines/sherlock/user_interface.h | 2 +- 10 files changed, 263 insertions(+), 264 deletions(-) delete mode 100644 engines/sherlock/graphics.cpp delete mode 100644 engines/sherlock/graphics.h create mode 100644 engines/sherlock/surface.cpp create mode 100644 engines/sherlock/surface.h diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp deleted file mode 100644 index 234928156a..0000000000 --- a/engines/sherlock/graphics.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "sherlock/graphics.h" -#include "sherlock/sherlock.h" -#include "common/system.h" -#include "graphics/palette.h" - -namespace Sherlock { - -Surface::Surface(uint16 width, uint16 height): _freePixels(true) { - create(width, height); -} - -Surface::Surface() : _freePixels(false) { -} - -Surface::~Surface() { - if (_freePixels) - free(); -} - -/** - * Sets up an internal surface with the specified dimensions that will be automatically freed - * when the surface object is destroyed - */ -void Surface::create(uint16 width, uint16 height) { - if (_freePixels) - free(); - - Graphics::Surface::create(width, height, Graphics::PixelFormat::createFormatCLUT8()); - _freePixels = true; -} - -/** - * Copy a surface into this one - */ -void Surface::blitFrom(const Graphics::Surface &src) { - blitFrom(src, Common::Point(0, 0)); -} - -/** - * Draws a surface at a given position within this surface - */ -void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt) { - Common::Rect drawRect(0, 0, src.w, src.h); - Common::Point destPt = pt; - - if (destPt.x < 0) { - drawRect.left += -destPt.x; - destPt.x = 0; - } - if (destPt.y < 0) { - drawRect.top += -destPt.y; - destPt.y = 0; - } - int right = destPt.x + src.w; - if (right > this->w) { - drawRect.right -= (right - this->w); - } - int bottom = destPt.y + src.h; - if (bottom > this->h) { - drawRect.bottom -= (bottom - this->h); - } - - if (drawRect.isValidRect()) - blitFrom(src, destPt, drawRect); -} - -/** - * Draws a sub-section of a surface at a given position within this surface - */ -void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt, - const Common::Rect &srcBounds) { - Common::Rect destRect(pt.x, pt.y, pt.x + srcBounds.width(), - pt.y + srcBounds.height()); - Common::Rect srcRect = srcBounds; - - if (clip(srcRect, destRect)) { - // Surface is at least partially or completely on-screen - addDirtyRect(destRect); - copyRectToSurface(src, destRect.left, destRect.top, srcRect); - } -} - -/** -* Draws an image frame at a given position within this surface with transparency -*/ -void Surface::transBlitFrom(const ImageFrame &src, const Common::Point &pt, - bool flipped, int overrideColor) { - transBlitFrom(src._frame, pt + src._offset, flipped, overrideColor); -} - -/** -* Draws a surface at a given position within this surface with transparency -*/ -void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &pt, - bool flipped, int overrideColor) { - Common::Rect drawRect(0, 0, src.w, src.h); - Common::Rect destRect(pt.x, pt.y, pt.x + src.w, pt.y + src.h); - - // Clip the display area to on-screen - if (!clip(drawRect, destRect)) - // It's completely off-screen - return; - - if (flipped) - drawRect = Common::Rect(src.w - drawRect.right, src.h - drawRect.bottom, - src.w - drawRect.left, src.h - drawRect.top); - - Common::Point destPt(destRect.left, destRect.top); - addDirtyRect(Common::Rect(destPt.x, destPt.y, destPt.x + drawRect.width(), - destPt.y + drawRect.height())); - - // Draw loop - const int TRANSPARENCY = 0xFF; - for (int yp = 0; yp < drawRect.height(); ++yp) { - const byte *srcP = (const byte *)src.getBasePtr( - flipped ? drawRect.right - 1 : drawRect.left, drawRect.top + yp); - byte *destP = (byte *)getBasePtr(destPt.x, destPt.y + yp); - - for (int xp = 0; xp < drawRect.width(); ++xp, ++destP) { - if (*srcP != TRANSPARENCY) - *destP = overrideColor ? overrideColor : *srcP; - - srcP = flipped ? srcP - 1 : srcP + 1; - } - } -} - -/** - * Fill a given area of the surface with a given color - */ -void Surface::fillRect(int x1, int y1, int x2, int y2, byte color) { - fillRect(Common::Rect(x1, y1, x2, y2), color); -} - -/** - * Fill a given area of the surface with a given color - */ -void Surface::fillRect(const Common::Rect &r, byte color) { - Graphics::Surface::fillRect(r, color); - addDirtyRect(r); -} - -/** - * Clips the given source bounds so the passed destBounds will be entirely on-screen - */ -bool Surface::clip(Common::Rect &srcBounds, Common::Rect &destBounds) { - if (destBounds.left >= this->w || destBounds.top >= this->h || - destBounds.right <= 0 || destBounds.bottom <= 0) - return false; - - // Clip the bounds if necessary to fit on-screen - if (destBounds.right > this->w) { - srcBounds.right -= destBounds.right - this->w; - destBounds.right = this->w; - } - - if (destBounds.bottom > this->h) { - srcBounds.bottom -= destBounds.bottom - this->h; - destBounds.bottom = this->h; - } - - if (destBounds.top < 0) { - srcBounds.top += -destBounds.top; - destBounds.top = 0; - } - - if (destBounds.left < 0) { - srcBounds.left += -destBounds.left; - destBounds.left = 0; - } - - return true; -} - -} // End of namespace Sherlock diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h deleted file mode 100644 index d4a1584968..0000000000 --- a/engines/sherlock/graphics.h +++ /dev/null @@ -1,60 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef SHERLOCK_GRAPHICS_H -#define SHERLOCK_GRAPHICS_H - -#include "common/rect.h" -#include "graphics/surface.h" -#include "sherlock/resources.h" - -namespace Sherlock { - -class Surface : public Graphics::Surface { -private: - bool _freePixels; - - bool clip(Common::Rect &srcBounds, Common::Rect &destBounds); -protected: - virtual void addDirtyRect(const Common::Rect &r) {} -public: - Surface(uint16 width, uint16 height); - Surface(); - virtual ~Surface(); - - void create(uint16 width, uint16 height); - void blitFrom(const Graphics::Surface &src); - void blitFrom(const Graphics::Surface &src, const Common::Point &pt); - void blitFrom(const Graphics::Surface &src, const Common::Point &pt, - const Common::Rect &srcBounds); - void transBlitFrom(const ImageFrame &src, const Common::Point &pt, - bool flipped = false, int overrideColor = 0); - void transBlitFrom(const Graphics::Surface &src, const Common::Point &pt, - bool flipped = false, int overrideColor = 0); - - void fillRect(int x1, int y1, int x2, int y2, byte color); - void fillRect(const Common::Rect &r, byte color); -}; - -} // End of namespace Sherlock - -#endif diff --git a/engines/sherlock/map.h b/engines/sherlock/map.h index 4432ec8553..4a418138b2 100644 --- a/engines/sherlock/map.h +++ b/engines/sherlock/map.h @@ -29,7 +29,7 @@ #include "common/serializer.h" #include "common/str.h" #include "common/str-array.h" -#include "sherlock/graphics.h" +#include "sherlock/surface.h" #include "sherlock/objects.h" namespace Sherlock { diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk index babd0c49a0..630c4faf32 100644 --- a/engines/sherlock/module.mk +++ b/engines/sherlock/module.mk @@ -9,7 +9,6 @@ MODULE_OBJS = \ debugger.o \ detection.o \ events.o \ - graphics.o \ inventory.o \ journal.o \ map.o \ @@ -22,6 +21,7 @@ MODULE_OBJS = \ settings.o \ sherlock.o \ sound.o \ + surface.o \ talk.o \ user_interface.o diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index a78b89b00c..b9ac3e79d6 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -21,7 +21,7 @@ */ #include "sherlock/saveload.h" -#include "sherlock/graphics.h" +#include "sherlock/surface.h" #include "sherlock/sherlock.h" #include "common/system.h" #include "graphics/scaler.h" diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 501506f8ec..1f3c23748f 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -26,8 +26,7 @@ #include "common/list.h" #include "common/rect.h" #include "common/serializer.h" -#include "graphics/surface.h" -#include "sherlock/graphics.h" +#include "sherlock/surface.h" #include "sherlock/resources.h" namespace Sherlock { diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 2a5d9ec627..a9a17a99f8 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -21,7 +21,7 @@ */ #include "sherlock/sherlock.h" -#include "sherlock/graphics.h" +#include "sherlock/surface.h" #include "common/scummsys.h" #include "common/config-manager.h" #include "common/debug-channels.h" diff --git a/engines/sherlock/surface.cpp b/engines/sherlock/surface.cpp new file mode 100644 index 0000000000..3e82f1dc5b --- /dev/null +++ b/engines/sherlock/surface.cpp @@ -0,0 +1,197 @@ +/* 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 "sherlock/surface.h" +#include "sherlock/sherlock.h" +#include "common/system.h" +#include "graphics/palette.h" + +namespace Sherlock { + +Surface::Surface(uint16 width, uint16 height): _freePixels(true) { + create(width, height); +} + +Surface::Surface() : _freePixels(false) { +} + +Surface::~Surface() { + if (_freePixels) + free(); +} + +/** + * Sets up an internal surface with the specified dimensions that will be automatically freed + * when the surface object is destroyed + */ +void Surface::create(uint16 width, uint16 height) { + if (_freePixels) + free(); + + Graphics::Surface::create(width, height, Graphics::PixelFormat::createFormatCLUT8()); + _freePixels = true; +} + +/** + * Copy a surface into this one + */ +void Surface::blitFrom(const Graphics::Surface &src) { + blitFrom(src, Common::Point(0, 0)); +} + +/** + * Draws a surface at a given position within this surface + */ +void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt) { + Common::Rect drawRect(0, 0, src.w, src.h); + Common::Point destPt = pt; + + if (destPt.x < 0) { + drawRect.left += -destPt.x; + destPt.x = 0; + } + if (destPt.y < 0) { + drawRect.top += -destPt.y; + destPt.y = 0; + } + int right = destPt.x + src.w; + if (right > this->w) { + drawRect.right -= (right - this->w); + } + int bottom = destPt.y + src.h; + if (bottom > this->h) { + drawRect.bottom -= (bottom - this->h); + } + + if (drawRect.isValidRect()) + blitFrom(src, destPt, drawRect); +} + +/** + * Draws a sub-section of a surface at a given position within this surface + */ +void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt, + const Common::Rect &srcBounds) { + Common::Rect destRect(pt.x, pt.y, pt.x + srcBounds.width(), + pt.y + srcBounds.height()); + Common::Rect srcRect = srcBounds; + + if (clip(srcRect, destRect)) { + // Surface is at least partially or completely on-screen + addDirtyRect(destRect); + copyRectToSurface(src, destRect.left, destRect.top, srcRect); + } +} + +/** +* Draws an image frame at a given position within this surface with transparency +*/ +void Surface::transBlitFrom(const ImageFrame &src, const Common::Point &pt, + bool flipped, int overrideColor) { + transBlitFrom(src._frame, pt + src._offset, flipped, overrideColor); +} + +/** +* Draws a surface at a given position within this surface with transparency +*/ +void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &pt, + bool flipped, int overrideColor) { + Common::Rect drawRect(0, 0, src.w, src.h); + Common::Rect destRect(pt.x, pt.y, pt.x + src.w, pt.y + src.h); + + // Clip the display area to on-screen + if (!clip(drawRect, destRect)) + // It's completely off-screen + return; + + if (flipped) + drawRect = Common::Rect(src.w - drawRect.right, src.h - drawRect.bottom, + src.w - drawRect.left, src.h - drawRect.top); + + Common::Point destPt(destRect.left, destRect.top); + addDirtyRect(Common::Rect(destPt.x, destPt.y, destPt.x + drawRect.width(), + destPt.y + drawRect.height())); + + // Draw loop + const int TRANSPARENCY = 0xFF; + for (int yp = 0; yp < drawRect.height(); ++yp) { + const byte *srcP = (const byte *)src.getBasePtr( + flipped ? drawRect.right - 1 : drawRect.left, drawRect.top + yp); + byte *destP = (byte *)getBasePtr(destPt.x, destPt.y + yp); + + for (int xp = 0; xp < drawRect.width(); ++xp, ++destP) { + if (*srcP != TRANSPARENCY) + *destP = overrideColor ? overrideColor : *srcP; + + srcP = flipped ? srcP - 1 : srcP + 1; + } + } +} + +/** + * Fill a given area of the surface with a given color + */ +void Surface::fillRect(int x1, int y1, int x2, int y2, byte color) { + fillRect(Common::Rect(x1, y1, x2, y2), color); +} + +/** + * Fill a given area of the surface with a given color + */ +void Surface::fillRect(const Common::Rect &r, byte color) { + Graphics::Surface::fillRect(r, color); + addDirtyRect(r); +} + +/** + * Clips the given source bounds so the passed destBounds will be entirely on-screen + */ +bool Surface::clip(Common::Rect &srcBounds, Common::Rect &destBounds) { + if (destBounds.left >= this->w || destBounds.top >= this->h || + destBounds.right <= 0 || destBounds.bottom <= 0) + return false; + + // Clip the bounds if necessary to fit on-screen + if (destBounds.right > this->w) { + srcBounds.right -= destBounds.right - this->w; + destBounds.right = this->w; + } + + if (destBounds.bottom > this->h) { + srcBounds.bottom -= destBounds.bottom - this->h; + destBounds.bottom = this->h; + } + + if (destBounds.top < 0) { + srcBounds.top += -destBounds.top; + destBounds.top = 0; + } + + if (destBounds.left < 0) { + srcBounds.left += -destBounds.left; + destBounds.left = 0; + } + + return true; +} + +} // End of namespace Sherlock diff --git a/engines/sherlock/surface.h b/engines/sherlock/surface.h new file mode 100644 index 0000000000..d4a1584968 --- /dev/null +++ b/engines/sherlock/surface.h @@ -0,0 +1,60 @@ +/* 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 SHERLOCK_GRAPHICS_H +#define SHERLOCK_GRAPHICS_H + +#include "common/rect.h" +#include "graphics/surface.h" +#include "sherlock/resources.h" + +namespace Sherlock { + +class Surface : public Graphics::Surface { +private: + bool _freePixels; + + bool clip(Common::Rect &srcBounds, Common::Rect &destBounds); +protected: + virtual void addDirtyRect(const Common::Rect &r) {} +public: + Surface(uint16 width, uint16 height); + Surface(); + virtual ~Surface(); + + void create(uint16 width, uint16 height); + void blitFrom(const Graphics::Surface &src); + void blitFrom(const Graphics::Surface &src, const Common::Point &pt); + void blitFrom(const Graphics::Surface &src, const Common::Point &pt, + const Common::Rect &srcBounds); + void transBlitFrom(const ImageFrame &src, const Common::Point &pt, + bool flipped = false, int overrideColor = 0); + void transBlitFrom(const Graphics::Surface &src, const Common::Point &pt, + bool flipped = false, int overrideColor = 0); + + void fillRect(int x1, int y1, int x2, int y2, byte color); + void fillRect(const Common::Rect &r, byte color); +}; + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index 79382a19fe..2ff60715e3 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -25,7 +25,7 @@ #include "common/scummsys.h" #include "common/events.h" -#include "sherlock/graphics.h" +#include "sherlock/surface.h" #include "sherlock/objects.h" #include "sherlock/resources.h" -- cgit v1.2.3 From 91d69c7dc151fabdc17b240e525181485c99b807 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 13 May 2015 21:24:42 -0400 Subject: SHERLOCK: Simplify blitFrom methods --- engines/sherlock/surface.cpp | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/engines/sherlock/surface.cpp b/engines/sherlock/surface.cpp index 3e82f1dc5b..2dfbdef77f 100644 --- a/engines/sherlock/surface.cpp +++ b/engines/sherlock/surface.cpp @@ -62,28 +62,7 @@ void Surface::blitFrom(const Graphics::Surface &src) { * Draws a surface at a given position within this surface */ void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt) { - Common::Rect drawRect(0, 0, src.w, src.h); - Common::Point destPt = pt; - - if (destPt.x < 0) { - drawRect.left += -destPt.x; - destPt.x = 0; - } - if (destPt.y < 0) { - drawRect.top += -destPt.y; - destPt.y = 0; - } - int right = destPt.x + src.w; - if (right > this->w) { - drawRect.right -= (right - this->w); - } - int bottom = destPt.y + src.h; - if (bottom > this->h) { - drawRect.bottom -= (bottom - this->h); - } - - if (drawRect.isValidRect()) - blitFrom(src, destPt, drawRect); + blitFrom(src, pt, Common::Rect(0, 0, src.w, src.h)); } /** @@ -91,11 +70,10 @@ void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt) { */ void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds) { - Common::Rect destRect(pt.x, pt.y, pt.x + srcBounds.width(), - pt.y + srcBounds.height()); Common::Rect srcRect = srcBounds; + Common::Rect destRect(pt.x, pt.y, pt.x + srcRect.width(), pt.y + srcRect.height()); - if (clip(srcRect, destRect)) { + if (srcRect.isValidRect() && clip(srcRect, destRect)) { // Surface is at least partially or completely on-screen addDirtyRect(destRect); copyRectToSurface(src, destRect.left, destRect.top, srcRect); -- cgit v1.2.3 From f987cda9f06e66962fb84b68fe060970c21d071f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 13 May 2015 21:39:08 -0400 Subject: SHERLOCK: Properly clear screen after fading to black --- engines/sherlock/screen.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 4cc3ba92e7..38bbb93800 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -141,6 +141,7 @@ void Screen::fadeToBlack(int speed) { } setPalette(tempPalette); + fillRect(Common::Rect(0, 0, this->w, this->h), 0); } /** -- cgit v1.2.3 From d3f1a76cc8336983d8bb36538fb8e6c520051935 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 14 May 2015 19:53:03 -0400 Subject: SHERLOCK: Default Files button to show GMM, with engine option to disable --- engines/sherlock/detection.cpp | 21 ++++++++++++++++++++- engines/sherlock/detection_tables.h | 2 +- engines/sherlock/sherlock.cpp | 4 ++++ engines/sherlock/sherlock.h | 1 + engines/sherlock/user_interface.cpp | 17 ++++++++++++----- 5 files changed, 38 insertions(+), 7 deletions(-) diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp index 78ab33bfd0..34fd919770 100644 --- a/engines/sherlock/detection.cpp +++ b/engines/sherlock/detection.cpp @@ -25,6 +25,7 @@ #include "sherlock/scalpel/scalpel.h" #include "sherlock/tattoo/tattoo.h" #include "common/system.h" +#include "common/translation.h" #include "engines/advancedDetector.h" namespace Sherlock { @@ -57,11 +58,29 @@ static const PlainGameDescriptor sherlockGames[] = { {0, 0} }; + +#define GAMEOPTION_ORIGINAL_SAVES GUIO_GAMEOPTIONS1 + +static const ADExtraGuiOptionsMap optionsList[] = { + { + GAMEOPTION_ORIGINAL_SAVES, + { + _s("Use original savegame dialog"), + _s("Files button in-game shows original savegame dialog rather than ScummVM menu"), + "OriginalSaves", + false + } + }, + + AD_EXTRA_GUI_OPTIONS_TERMINATOR +}; + #include "sherlock/detection_tables.h" class SherlockMetaEngine : public AdvancedMetaEngine { public: - SherlockMetaEngine() : AdvancedMetaEngine(Sherlock::gameDescriptions, sizeof(Sherlock::SherlockGameDescription), sherlockGames) {} + SherlockMetaEngine() : AdvancedMetaEngine(Sherlock::gameDescriptions, sizeof(Sherlock::SherlockGameDescription), + sherlockGames, optionsList) {} virtual const char *getName() const { return "Sherlock Engine"; diff --git a/engines/sherlock/detection_tables.h b/engines/sherlock/detection_tables.h index 975b7323ec..8300a0ffcf 100644 --- a/engines/sherlock/detection_tables.h +++ b/engines/sherlock/detection_tables.h @@ -33,7 +33,7 @@ static const SherlockGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE | ADGF_NO_FLAGS, - GUIO1(GUIO_NOSPEECH) + GUIO2(GUIO_NOSPEECH, GAMEOPTION_ORIGINAL_SAVES) }, GType_SerratedScalpel, }, diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index a9a17a99f8..41c41473d7 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -48,6 +48,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _useEpilogue2 = false; _loadGameSlot = -1; _canLoadSave = false; + _showOriginalSavesDialog = false; } SherlockEngine::~SherlockEngine() { @@ -104,6 +105,9 @@ Common::Error SherlockEngine::run() { // Initialize the engine initialize(); + // Flag for whether to show original saves dialog rather than the ScummVM GMM + _showOriginalSavesDialog = ConfMan.hasKey("OriginalSaves") && ConfMan.getBool("OriginalSaves"); + // If requested, load a savegame instead of showing the intro if (ConfMan.hasKey("save_slot")) { int saveSlot = ConfMan.getInt("save_slot"); diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 501fdcb292..33e4a45b40 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -108,6 +108,7 @@ public: bool _useEpilogue2; int _loadGameSlot; bool _canLoadSave; + bool _showOriginalSavesDialog; public: SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc); virtual ~SherlockEngine(); diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index aa6bf2ba81..85838f8a93 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1420,17 +1420,24 @@ void UserInterface::doMainControl() { break; case 'F': pushButton(10); - _menuMode = FILES_MODE; // Create a thumbnail of the current screen before the files dialog is shown, in case // the user saves the game saves.createThumbnail(); - // Display the dialog - saves.drawInterface(); - _selector = _oldSelector = -1; - _windowOpen = true; + + if (_vm->_showOriginalSavesDialog) { + // Show the original dialog + _menuMode = FILES_MODE; + saves.drawInterface(); + _windowOpen = true; + } else { + // Show the ScummVM GMM instead + _vm->_canLoadSave = true; + _vm->openMainMenuDialog(); + _vm->_canLoadSave = false; + } break; case 'S': pushButton(11); -- cgit v1.2.3 From 8d2ec6f9fa45fc17d517db36fa688b12eb809681 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Fri, 15 May 2015 09:55:35 +0200 Subject: SHERLOCK: Remove a couple of unused variables in inventory --- engines/sherlock/inventory.cpp | 5 ----- engines/sherlock/inventory.h | 2 -- 2 files changed, 7 deletions(-) diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index d8c0104e6c..1997807d15 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -49,8 +49,6 @@ Inventory::Inventory(SherlockEngine *vm) : Common::Array(), _vm(v _invGraphicsLoaded = false; _invIndex = 0; _holdings = 0; - _oldFlag = 0; - _invFlag = 0; _invMode = INVMODE_EXIT; } @@ -215,7 +213,6 @@ void Inventory::drawInventory(int flag) { UserInterface &ui = *_vm->_ui; int tempFlag = flag; - _oldFlag = 7; loadInv(); if (flag == 128) { @@ -257,10 +254,8 @@ void Inventory::drawInventory(int flag) { if (flag) { ui._oldKey = INVENTORY_COMMANDS[flag]; - _oldFlag = flag; } else { ui._oldKey = -1; - _invFlag = 6; } invCommands(0); diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index f4cea7729a..eb5aebdd7c 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -75,8 +75,6 @@ public: int _holdings; // Used to hold number of visible items in active inventory. // Since Inventory array also contains some special hidden items void freeGraphics(); - int _oldFlag; - int _invFlag; public: Inventory(SherlockEngine *vm); ~Inventory(); -- cgit v1.2.3 From 07e9262ee7f38b31743d940fa8238dbbaeede864 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 15 May 2015 19:36:39 -0400 Subject: SHERLOCK: Change save extra option to use more standard originalsaveload --- engines/sherlock/detection.cpp | 2 +- engines/sherlock/sherlock.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp index 34fd919770..2804ec1d31 100644 --- a/engines/sherlock/detection.cpp +++ b/engines/sherlock/detection.cpp @@ -67,7 +67,7 @@ static const ADExtraGuiOptionsMap optionsList[] = { { _s("Use original savegame dialog"), _s("Files button in-game shows original savegame dialog rather than ScummVM menu"), - "OriginalSaves", + "originalsaveload", false } }, diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 41c41473d7..a84eedbd04 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -106,7 +106,7 @@ Common::Error SherlockEngine::run() { initialize(); // Flag for whether to show original saves dialog rather than the ScummVM GMM - _showOriginalSavesDialog = ConfMan.hasKey("OriginalSaves") && ConfMan.getBool("OriginalSaves"); + _showOriginalSavesDialog = ConfMan.hasKey("originalsaveload") && ConfMan.getBool("originalsaveload"); // If requested, load a savegame instead of showing the intro if (ConfMan.hasKey("save_slot")) { -- cgit v1.2.3 From a77c6dd43f797c33c7537df6e0cd1a79586087b5 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 15 May 2015 19:40:28 -0400 Subject: SHERLOCK: Fix mismatched alloc/free in decompressed resource buffers --- engines/sherlock/decompress.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/decompress.cpp b/engines/sherlock/decompress.cpp index b781285471..2157d47eb8 100644 --- a/engines/sherlock/decompress.cpp +++ b/engines/sherlock/decompress.cpp @@ -40,7 +40,7 @@ Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source, int uint16 lzWindowPos; uint16 cmd; - byte *outBuffer = new byte[outSize]; + byte *outBuffer = (byte *)malloc(outSize); byte *outBufferEnd = outBuffer + outSize; Common::MemoryReadStream *outS = new Common::MemoryReadStream(outBuffer, outSize, DisposeAfterUse::YES); -- cgit v1.2.3 From 07907819c18d075c39158d2d35f5949e13497127 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 15 May 2015 19:42:18 -0400 Subject: SHERLOCK: Fix saving mute flags in saveConfig --- engines/sherlock/sherlock.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index a84eedbd04..d6fe0c69aa 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -231,9 +231,9 @@ void SherlockEngine::loadConfig() { * Saves game configuration information */ void SherlockEngine::saveConfig() { - ConfMan.setBool("mute", _sound->_digitized); - ConfMan.setBool("music_mute", _sound->_music); - ConfMan.setBool("speech_mute", _sound->_voices); + ConfMan.setBool("mute", !_sound->_digitized); + ConfMan.setBool("music_mute", !_sound->_music); + ConfMan.setBool("speech_mute", !_sound->_voices); ConfMan.setInt("font", _screen->fontNumber()); ConfMan.setBool("fade_style", _screen->_fadeStyle); -- cgit v1.2.3 From d9a7d87b1908da6f249a1b16110ae3fd3cc9ed07 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 15 May 2015 19:46:29 -0400 Subject: SHERLOCK: Fix positioning of Quit Yes/No buttons --- engines/sherlock/user_interface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 85838f8a93..1521421c15 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -919,7 +919,7 @@ void UserInterface::doEnvControl() { screen.print(Common::Point(0, CONTROLS_Y + 20), INV_FOREGROUND, "Are you sure you wish to Quit ?"); screen.vgaBar(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y + 10), BORDER_COLOR); - screen.makeButton(Common::Rect(112, CONTROLS_Y, 150, CONTROLS_Y + 10), 136 - screen.stringWidth("Yes") / 2, "Yes"); + screen.makeButton(Common::Rect(112, CONTROLS_Y, 160, CONTROLS_Y + 10), 136 - screen.stringWidth("Yes") / 2, "Yes"); screen.makeButton(Common::Rect(161, CONTROLS_Y, 209, CONTROLS_Y + 10), 184 - screen.stringWidth("No") / 2, "No"); screen.slamArea(112, CONTROLS_Y, 97, 10); -- cgit v1.2.3 From 62ce7a9c839f82121c14ce8357d107bc1ba70244 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 15 May 2015 20:02:40 -0400 Subject: SHERLOCK: Use ConfMan.registerDefault to simply reading options --- engines/sherlock/sherlock.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index d6fe0c69aa..95da79d988 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -106,7 +106,7 @@ Common::Error SherlockEngine::run() { initialize(); // Flag for whether to show original saves dialog rather than the ScummVM GMM - _showOriginalSavesDialog = ConfMan.hasKey("originalsaveload") && ConfMan.getBool("originalsaveload"); + _showOriginalSavesDialog = ConfMan.getBool("originalsaveload"); // If requested, load a savegame instead of showing the intro if (ConfMan.hasKey("save_slot")) { @@ -214,17 +214,18 @@ void SherlockEngine::loadConfig() { // Load sound settings syncSoundSettings(); - // Load other settings - if (ConfMan.hasKey("font")) - _screen->setFont(ConfMan.getInt("font")); - if (ConfMan.hasKey("fade_style")) - _screen->_fadeStyle = ConfMan.getBool("fade_style"); - if (ConfMan.hasKey("help_style")) - _ui->_helpStyle = ConfMan.getBool("help_style"); - if (ConfMan.hasKey("window_style")) - _ui->_windowStyle = ConfMan.getInt("window_style"); - if (ConfMan.hasKey("portraits_on")) - _people->_portraitsOn = ConfMan.getBool("portraits_on"); + ConfMan.registerDefault("font", 1); + ConfMan.registerDefault("fade_style", false); + ConfMan.registerDefault("help_style", false); + ConfMan.registerDefault("window_style", 1); + ConfMan.registerDefault("portraits_on", true); + ConfMan.registerDefault("originalsaveload", false); + + _screen->setFont(ConfMan.getInt("font")); + _screen->_fadeStyle = ConfMan.getBool("fade_style"); + _ui->_helpStyle = ConfMan.getBool("help_style"); + _ui->_windowStyle = ConfMan.getInt("window_style"); + _people->_portraitsOn = ConfMan.getBool("portraits_on"); } /** -- cgit v1.2.3 From 95ce29ac7470435dbec167df526cf4ff38fc8805 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 15 May 2015 20:44:12 -0400 Subject: SHERLOCK: Fix random pixel transitions, and make it the default fade style --- engines/sherlock/screen.cpp | 2 +- engines/sherlock/sherlock.cpp | 3 +++ engines/sherlock/surface.cpp | 7 +++++++ engines/sherlock/surface.h | 2 ++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 38bbb93800..cbf18f146f 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -217,7 +217,7 @@ void Screen::randomTransition() { if (offset < (SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCREEN_HEIGHT)) *((byte *)getPixels() + offset) = *((const byte *)_backBuffer->getPixels() + offset); - if (idx != 0 && (idx % 100) == 0) { + if (idx != 0 && (idx % 300) == 0) { // Ensure there's a full screen dirty rect for the next frame update if (_dirtyRects.empty()) addDirtyRect(Common::Rect(0, 0, this->w, this->h)); diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 95da79d988..81d461b161 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -129,6 +129,9 @@ Common::Error SherlockEngine::run() { if (shouldQuit()) break; + // Clear the screen + _screen->clear(); + // Reset UI flags _ui->reset(); diff --git a/engines/sherlock/surface.cpp b/engines/sherlock/surface.cpp index 2dfbdef77f..36e625794c 100644 --- a/engines/sherlock/surface.cpp +++ b/engines/sherlock/surface.cpp @@ -172,4 +172,11 @@ bool Surface::clip(Common::Rect &srcBounds, Common::Rect &destBounds) { return true; } +/** + * Clear the screen + */ +void Surface::clear() { + fillRect(Common::Rect(0, 0, this->w, this->h), 0); +} + } // End of namespace Sherlock diff --git a/engines/sherlock/surface.h b/engines/sherlock/surface.h index d4a1584968..b2a759aa8d 100644 --- a/engines/sherlock/surface.h +++ b/engines/sherlock/surface.h @@ -53,6 +53,8 @@ public: void fillRect(int x1, int y1, int x2, int y2, byte color); void fillRect(const Common::Rect &r, byte color); + + void clear(); }; } // End of namespace Sherlock -- cgit v1.2.3 From 8c7f5bf92fc3eadddf2e2dd69548ad9433e7fdb3 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 16 May 2015 07:18:36 -0400 Subject: SHERLOCK: Fix default fade style option --- engines/sherlock/sherlock.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 81d461b161..64fabc78df 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -218,7 +218,7 @@ void SherlockEngine::loadConfig() { syncSoundSettings(); ConfMan.registerDefault("font", 1); - ConfMan.registerDefault("fade_style", false); + ConfMan.registerDefault("fade_style", true); ConfMan.registerDefault("help_style", false); ConfMan.registerDefault("window_style", 1); ConfMan.registerDefault("portraits_on", true); -- cgit v1.2.3 From 052e04c00574720192c2975c6549fd33c6a23390 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 16 May 2015 08:56:50 -0400 Subject: SHERLOCK: Merged decompression code into Resources class --- engines/sherlock/decompress.cpp | 80 ----------------------------------------- engines/sherlock/decompress.h | 36 ------------------- engines/sherlock/module.mk | 1 - engines/sherlock/resources.cpp | 66 +++++++++++++++++++++++++++++++--- engines/sherlock/resources.h | 9 +++-- engines/sherlock/scene.cpp | 15 ++++---- engines/sherlock/sherlock.cpp | 2 +- 7 files changed, 77 insertions(+), 132 deletions(-) delete mode 100644 engines/sherlock/decompress.cpp delete mode 100644 engines/sherlock/decompress.h diff --git a/engines/sherlock/decompress.cpp b/engines/sherlock/decompress.cpp deleted file mode 100644 index 2157d47eb8..0000000000 --- a/engines/sherlock/decompress.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "sherlock/decompress.h" - -namespace Sherlock { - -/** - * Decompresses an LZW compressed resource. If no outSize is specified, it will - * decompress the entire resource. If, however, an explicit size is specified, - * then it means we're already within a resource, and only want to decompress - * part of it. - */ -Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source, int32 outSize) { - if (outSize == -1) { - source.seek(4); - outSize = source.readSint32LE(); - } - - byte lzWindow[4096]; - uint16 lzWindowPos; - uint16 cmd; - - byte *outBuffer = (byte *)malloc(outSize); - byte *outBufferEnd = outBuffer + outSize; - Common::MemoryReadStream *outS = new Common::MemoryReadStream(outBuffer, outSize, DisposeAfterUse::YES); - - memset(lzWindow, 0xFF, 0xFEE); - lzWindowPos = 0xFEE; - cmd = 0; - - do { - cmd >>= 1; - if (!(cmd & 0x100)) - cmd = source.readByte() | 0xFF00; - - if (cmd & 1) { - byte literal = source.readByte(); - *outBuffer++ = literal; - lzWindow[lzWindowPos] = literal; - lzWindowPos = (lzWindowPos + 1) & 0x0FFF; - } else { - int copyPos, copyLen; - copyPos = source.readByte(); - copyLen = source.readByte(); - copyPos = copyPos | ((copyLen & 0xF0) << 4); - copyLen = (copyLen & 0x0F) + 3; - while (copyLen--) { - byte literal = lzWindow[copyPos]; - copyPos = (copyPos + 1) & 0x0FFF; - *outBuffer++ = literal; - lzWindow[lzWindowPos] = literal; - lzWindowPos = (lzWindowPos + 1) & 0x0FFF; - } - } - } while (outBuffer < outBufferEnd); - - return outS; -} - -} // namespace Sherlock diff --git a/engines/sherlock/decompress.h b/engines/sherlock/decompress.h deleted file mode 100644 index 694f56aa65..0000000000 --- a/engines/sherlock/decompress.h +++ /dev/null @@ -1,36 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef SHERLOCK_DECOMPRESS_H -#define SHERLOCK_DECOMPRESS_H - -#include "common/memstream.h" - -namespace Sherlock { - -#include "common/stream.h" - -Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source, int32 outSize = -1); - -} // namespace Sherlock - -#endif diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk index 630c4faf32..2ded999ed1 100644 --- a/engines/sherlock/module.mk +++ b/engines/sherlock/module.mk @@ -5,7 +5,6 @@ MODULE_OBJS = \ scalpel/scalpel.o \ tattoo/tattoo.o \ animation.o \ - decompress.o \ debugger.o \ detection.o \ events.o \ diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index e990013cb3..b5f4f5f6dd 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -21,14 +21,14 @@ */ #include "sherlock/resources.h" -#include "sherlock/decompress.h" #include "sherlock/screen.h" #include "sherlock/sherlock.h" #include "common/debug.h" +#include "common/memstream.h" namespace Sherlock { -Cache::Cache() { +Cache::Cache(SherlockEngine *vm): _vm(vm) { } /** @@ -76,7 +76,7 @@ void Cache::load(const Common::String &name, Common::SeekableReadStream &stream) // Check whether the file is compressed if (signature == MKTAG('L', 'Z', 'V', 26)) { // It's compressed, so decompress the file and store it's data in the cache entry - Common::SeekableReadStream *decompressed = decompressLZ(stream); + Common::SeekableReadStream *decompressed = _vm->_res->decompressLZ(stream); cacheEntry.resize(decompressed->size()); decompressed->read(&cacheEntry[0], decompressed->size()); @@ -99,7 +99,7 @@ Common::SeekableReadStream *Cache::get(const Common::String &filename) const { /*----------------------------------------------------------------*/ -Resources::Resources() { +Resources::Resources(SherlockEngine *vm): _vm(vm), _cache(vm) { _resourceIndex = -1; addToCache("vgs.lib"); @@ -404,4 +404,62 @@ void ImageFile::decompressFrame(ImageFrame &frame, const byte *src) { } } +/** + * Decompress an LZW compressed resource + */ +Common::SeekableReadStream *Resources::decompressLZ(Common::SeekableReadStream &source) { + if (_vm->getGameID() == GType_SerratedScalpel) { + uint32 id = source.readUint32BE(); + assert(id == MKTAG('L', 'Z', 'V', 0x1A)); + } + + uint32 size = source.readUint32LE(); + return decompressLZ(source, size); +} + +/** + * Decompresses an LZW block of data with a specified output size + */ +Common::SeekableReadStream *Resources::decompressLZ(Common::SeekableReadStream &source, uint32 outSize) { + byte lzWindow[4096]; + uint16 lzWindowPos; + uint16 cmd; + + byte *outBuffer = (byte *)malloc(outSize); + byte *outBufferEnd = outBuffer + outSize; + Common::MemoryReadStream *outS = new Common::MemoryReadStream(outBuffer, outSize, DisposeAfterUse::YES); + + memset(lzWindow, 0xFF, 0xFEE); + lzWindowPos = 0xFEE; + cmd = 0; + + do { + cmd >>= 1; + if (!(cmd & 0x100)) + cmd = source.readByte() | 0xFF00; + + if (cmd & 1) { + byte literal = source.readByte(); + *outBuffer++ = literal; + lzWindow[lzWindowPos] = literal; + lzWindowPos = (lzWindowPos + 1) & 0x0FFF; + } else { + int copyPos, copyLen; + copyPos = source.readByte(); + copyLen = source.readByte(); + copyPos = copyPos | ((copyLen & 0xF0) << 4); + copyLen = (copyLen & 0x0F) + 3; + while (copyLen--) { + byte literal = lzWindow[copyPos]; + copyPos = (copyPos + 1) & 0x0FFF; + *outBuffer++ = literal; + lzWindow[lzWindowPos] = literal; + lzWindowPos = (lzWindowPos + 1) & 0x0FFF; + } + } + } while (outBuffer < outBufferEnd); + + return outS; +} + } // End of namespace Sherlock diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h index e1f97f1def..d5e83a1745 100644 --- a/engines/sherlock/resources.h +++ b/engines/sherlock/resources.h @@ -52,9 +52,10 @@ class SherlockEngine; class Cache { private: + SherlockEngine *_vm; CacheHash _resources; public: - Cache(); + Cache(SherlockEngine *_vm); bool isCached(const Common::String &filename) const; @@ -66,13 +67,14 @@ public: class Resources { private: + SherlockEngine *_vm; Cache _cache; LibraryIndexes _indexes; int _resourceIndex; void loadLibraryIndex(const Common::String &libFilename, Common::SeekableReadStream *stream); public: - Resources(); + Resources(SherlockEngine *vm); void addToCache(const Common::String &filename); void addToCache(const Common::String &filename, const Common::String &libFilename); @@ -86,6 +88,9 @@ public: bool exists(const Common::String &filename) const; int resourceIndex() const; + + static Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source, uint32 outSize); + Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source); }; struct ImageFrame { diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 093c305a97..9fbf25ce98 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -23,7 +23,6 @@ #include "sherlock/scene.h" #include "sherlock/sherlock.h" #include "sherlock/scalpel/scalpel.h" -#include "sherlock/decompress.h" namespace Sherlock { @@ -274,7 +273,7 @@ bool Scene::loadScene(const Common::String &filename) { // Read information Common::SeekableReadStream *infoStream = !_lzwMode ? rrmStream : - decompressLZ(*rrmStream, bgHeader._numImages * 569 + + Resources::decompressLZ(*rrmStream, bgHeader._numImages * 569 + bgHeader._descSize + bgHeader._seqSize); _bgShapes.resize(bgHeader._numStructs); @@ -302,7 +301,7 @@ bool Scene::loadScene(const Common::String &filename) { // Read in the image data Common::SeekableReadStream *imageStream = _lzwMode ? - decompressLZ(*rrmStream, bgInfo[idx]._filesize) : + Resources::decompressLZ(*rrmStream, bgInfo[idx]._filesize) : rrmStream->readStream(bgInfo[idx]._filesize); _images[idx + 1]._images = new ImageFile(*imageStream); @@ -331,7 +330,7 @@ bool Scene::loadScene(const Common::String &filename) { _cAnim.clear(); if (bgHeader._numcAnimations) { Common::SeekableReadStream *canimStream = _lzwMode ? - decompressLZ(*rrmStream, 65 * bgHeader._numcAnimations) : + Resources::decompressLZ(*rrmStream, 65 * bgHeader._numcAnimations) : rrmStream->readStream(65 * bgHeader._numcAnimations); _cAnim.resize(bgHeader._numcAnimations); @@ -344,7 +343,7 @@ bool Scene::loadScene(const Common::String &filename) { // Read in the room bounding areas int size = rrmStream->readUint16LE(); Common::SeekableReadStream *boundsStream = !_lzwMode ? rrmStream : - decompressLZ(*rrmStream, size); + Resources::decompressLZ(*rrmStream, size); _zones.resize(size / 10); for (uint idx = 0; idx < _zones.size(); ++idx) { @@ -371,7 +370,7 @@ bool Scene::loadScene(const Common::String &filename) { // Read in the walk data size = rrmStream->readUint16LE(); Common::SeekableReadStream *walkStream = !_lzwMode ? rrmStream : - decompressLZ(*rrmStream, size); + Resources::decompressLZ(*rrmStream, size); _walkData.resize(size); walkStream->read(&_walkData[0], size); @@ -408,7 +407,7 @@ bool Scene::loadScene(const Common::String &filename) { // Read in the background Common::SeekableReadStream *bgStream = !_lzwMode ? rrmStream : - decompressLZ(*rrmStream, SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT); + Resources::decompressLZ(*rrmStream, SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT); bgStream->read(screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT); @@ -982,7 +981,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) { // Load the canimation into the cache Common::SeekableReadStream *imgStream = !_lzwMode ? rrmStream->readStream(cAnim._size) : - decompressLZ(*rrmStream, cAnim._size); + Resources::decompressLZ(*rrmStream, cAnim._size); res.addToCache(fname, *imgStream); delete imgStream; diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 64fabc78df..09a8ef18ef 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -79,7 +79,7 @@ void SherlockEngine::initialize() { ImageFile::setVm(this); Object::setVm(this); Sprite::setVm(this); - _res = new Resources(); + _res = new Resources(this); _animation = new Animation(this); _debugger = new Debugger(this); _events = new Events(this); -- cgit v1.2.3 From 96e929f5233b23917169c7d0121e9c1e264455c1 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 16 May 2015 09:03:53 -0400 Subject: SHERLOCK: Clear screen before transitioning to the map --- engines/sherlock/map.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index e178dece0c..7fca4ea5f3 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -140,6 +140,10 @@ int Map::show() { int oldFont = screen.fontNumber(); screen.setFont(0); + // Initial screen clear + screen._backBuffer1.clear(); + screen.clear(); + // Load the entire map ImageFile bigMap("bigmap.vgs"); screen.setPalette(bigMap._palette); -- cgit v1.2.3 From e909f1325f15482961e8b7c7b04018b582ea1046 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 16 May 2015 17:03:48 -0400 Subject: SHERLOCK: Fix reading scene shapes when compressed --- engines/sherlock/scene.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 9fbf25ce98..619c253bed 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -273,7 +273,7 @@ bool Scene::loadScene(const Common::String &filename) { // Read information Common::SeekableReadStream *infoStream = !_lzwMode ? rrmStream : - Resources::decompressLZ(*rrmStream, bgHeader._numImages * 569 + + Resources::decompressLZ(*rrmStream, bgHeader._numStructs * 569 + bgHeader._descSize + bgHeader._seqSize); _bgShapes.resize(bgHeader._numStructs); -- cgit v1.2.3 From 239562fc01e113383cac8bb5b44e3a67d904538e Mon Sep 17 00:00:00 2001 From: Strangerke Date: Sun, 17 May 2015 14:33:57 +0200 Subject: SHERLOCK: Better decoding of ADPCM 4bit sounds, courtesy of m_kiewitz --- engines/sherlock/sound.cpp | 72 +++++++++++++++++++++++++++++----------------- engines/sherlock/sound.h | 3 +- 2 files changed, 47 insertions(+), 28 deletions(-) diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index 59098c32cc..9f36d6d9b7 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -63,29 +63,44 @@ void Sound::loadSound(const Common::String &name, int priority) { // No implementation required in ScummVM } -char Sound::decodeSample(char sample, byte& prediction, int& step) { - char diff = ((sample & 0x07) << step); - - if (sample & 0x08) { - if (prediction > diff) - prediction = prediction - ((sample & 0x07) << step); - else - prediction = 0; +static int8 creativeADPCM_ScaleMap[64] = { + 0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7, + 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15, + 2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30, + 4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60 +}; + +static uint8 creativeADPCM_AdjustMap[64] = { + 0, 0, 0, 0, 0, 16, 16, 16, + 0, 0, 0, 0, 0, 16, 16, 16, + 240, 0, 0, 0, 0, 16, 16, 16, + 240, 0, 0, 0, 0, 16, 16, 16, + 240, 0, 0, 0, 0, 16, 16, 16, + 240, 0, 0, 0, 0, 16, 16, 16, + 240, 0, 0, 0, 0, 0, 0, 0, + 240, 0, 0, 0, 0, 0, 0, 0 +}; + +byte Sound::decodeSample(byte sample, byte& reference, int16& scale) { + int16 samp = sample + scale; + int16 ref = 0; + + // clip bad ADPCM-4 sample + CLIP(samp, 0, 63); + + ref = reference + creativeADPCM_ScaleMap[samp]; + if (ref > 0xff) { + reference = 0xff; } else { - if (prediction < 0xff - diff) - prediction = prediction + ((sample&0x07) << step); - else - prediction = 0xff; - } - - - if ((sample & 0x07) >= 5 && step < 3) { - step ++; - } else if ((sample & 0x07) == 0 && step > 0) { - step --; + if (ref < 0x00) { + reference = 0; + } else { + reference = (uint8)(ref & 0xff); + } } - return prediction; + scale = (scale + creativeADPCM_AdjustMap[samp]) & 0xff; + return reference; } bool Sound::playSound(const Common::String &name, WaitType waitType, int priority) { @@ -94,7 +109,7 @@ bool Sound::playSound(const Common::String &name, WaitType waitType, int priorit Common::String filename = name; if (!filename.contains('.')) filename += ".SND"; - + Common::SeekableReadStream *stream = _vm->_res->load(filename); if (!stream) @@ -107,16 +122,18 @@ bool Sound::playSound(const Common::String &name, WaitType waitType, int priorit byte *ptr = data; stream->read(ptr, size); + assert(size > 2); + byte *decoded = (byte *)malloc((size - 1) * 2); - // +127 to eliminate the pop when the sound starts (signed vs unsigned PCM). Still does not help with the pop at the end - byte prediction = (ptr[0] & 0x0f) + 127; - int step = 0; + // Holmes uses Creative ADPCM 4-bit data int counter = 0; + byte reference = ptr[0]; + int16 scale = 0; for(int i = 1; i < size; i++) { - decoded[counter++] = decodeSample((ptr[i]>>4)&0x0f, prediction, step); - decoded[counter++] = decodeSample((ptr[i]>>0)&0x0f, prediction, step); + decoded[counter++] = decodeSample((ptr[i]>>4)&0x0f, reference, scale); + decoded[counter++] = decodeSample((ptr[i]>>0)&0x0f, reference, scale); } free(data); @@ -149,7 +166,7 @@ bool Sound::playSound(const Common::String &name, WaitType waitType, int priorit break; } } while (!_vm->shouldQuit() && _mixer->isSoundHandleActive(_effectsHandle)); - + _soundPlaying = false; _mixer->stopHandle(_effectsHandle); @@ -234,3 +251,4 @@ void Sound::freeDigiSound() { } } // End of namespace Sherlock + diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index 659df57bc3..4d94c58f6f 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -46,7 +46,7 @@ private: Audio::SoundHandle _effectsHandle; int _curPriority; - char decodeSample(char sample, byte& prediction, int& step); + byte decodeSample(byte sample, byte& reference, int16& scale); public: bool _digitized; bool _music; @@ -83,3 +83,4 @@ public: } // End of namespace Sherlock #endif + -- cgit v1.2.3 From 4af7b58e94bfa505900d363d0bb5c31a0e1f7278 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Sun, 17 May 2015 15:04:22 +0200 Subject: SHERLOCK: Fix compilation for gcc --- engines/sherlock/sound.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index 9f36d6d9b7..40aa4fa81a 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -86,7 +86,7 @@ byte Sound::decodeSample(byte sample, byte& reference, int16& scale) { int16 ref = 0; // clip bad ADPCM-4 sample - CLIP(samp, 0, 63); + CLIP(samp, 0, 63); ref = reference + creativeADPCM_ScaleMap[samp]; if (ref > 0xff) { -- cgit v1.2.3 From 7cd4d1561032104657544d3deda9aada5c06da45 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 17 May 2015 11:50:39 -0400 Subject: SHERLOCK: Fix scene loading when using a Small installation --- engines/sherlock/scene.cpp | 58 +++++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 619c253bed..3dcfddd428 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -272,26 +272,52 @@ bool Scene::loadScene(const Common::String &filename) { bgInfo[idx].load(*rrmStream); // Read information - Common::SeekableReadStream *infoStream = !_lzwMode ? rrmStream : - Resources::decompressLZ(*rrmStream, bgHeader._numStructs * 569 + - bgHeader._descSize + bgHeader._seqSize); - - _bgShapes.resize(bgHeader._numStructs); - for (int idx = 0; idx < bgHeader._numStructs; ++idx) - _bgShapes[idx].load(*infoStream); + if (!_lzwMode) { + _bgShapes.resize(bgHeader._numStructs); + for (int idx = 0; idx < bgHeader._numStructs; ++idx) + _bgShapes[idx].load(*rrmStream); + + if (bgHeader._descSize) { + _descText.resize(bgHeader._descSize); + rrmStream->read(&_descText[0], bgHeader._descSize); + } - if (bgHeader._descSize) { - _descText.resize(bgHeader._descSize); - infoStream->read(&_descText[0], bgHeader._descSize); - } + if (bgHeader._seqSize) { + _sequenceBuffer.resize(bgHeader._seqSize); + rrmStream->read(&_sequenceBuffer[0], bgHeader._seqSize); + } + } else { + Common::SeekableReadStream *infoStream; + + // Read shapes + infoStream = Resources::decompressLZ(*rrmStream, bgHeader._numStructs * 569); - if (bgHeader._seqSize) { - _sequenceBuffer.resize(bgHeader._seqSize); - infoStream->read(&_sequenceBuffer[0], bgHeader._seqSize); - } + _bgShapes.resize(bgHeader._numStructs); + for (int idx = 0; idx < bgHeader._numStructs; ++idx) + _bgShapes[idx].load(*infoStream); - if (_lzwMode) delete infoStream; + + // Read description texts + if (bgHeader._descSize) { + infoStream = Resources::decompressLZ(*rrmStream, bgHeader._descSize); + + _descText.resize(bgHeader._descSize); + infoStream->read(&_descText[0], bgHeader._descSize); + + delete infoStream; + } + + // Read sequences + if (bgHeader._seqSize) { + infoStream = Resources::decompressLZ(*rrmStream, bgHeader._seqSize); + + _sequenceBuffer.resize(bgHeader._seqSize); + infoStream->read(&_sequenceBuffer[0], bgHeader._seqSize); + + delete infoStream; + } + } // Set up the list of images used by the scene _images.resize(bgHeader._numImages + 1); -- cgit v1.2.3 From 2abb5f19772125ec5b91619e39ffd2fd4b733641 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 17 May 2015 14:01:35 -0400 Subject: SHERLOCK: Fix decompression of resources from library files --- engines/sherlock/resources.cpp | 32 +++++++++++++++++++------------- engines/sherlock/resources.h | 2 ++ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index b5f4f5f6dd..f6fbded9b1 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -164,20 +164,10 @@ Common::SeekableReadStream *Resources::load(const Common::String &filename) { stream->seek(entry._offset); Common::SeekableReadStream *resStream = stream->readStream(entry._size); + decompressIfNecessary(resStream); - // Check whether the file is compressed - if (resStream->readUint32BE() == MKTAG('L', 'Z', 'V', 26)) { - resStream->seek(0); - // It's compressed, so decompress the sub-file and return it - Common::SeekableReadStream *decompressed = decompressLZ(*resStream); - delete stream; - delete resStream; - return decompressed; - } else { - resStream->seek(0); - delete stream; - return resStream; - } + delete stream; + return resStream; } } @@ -188,10 +178,25 @@ Common::SeekableReadStream *Resources::load(const Common::String &filename) { Common::SeekableReadStream *stream = f.readStream(f.size()); f.close(); + decompressIfNecessary(stream); return stream; } +/** + * Checks the passed stream, and if is compressed, deletes it and replaces it with it's uncompressed data + */ +void Resources::decompressIfNecessary(Common::SeekableReadStream *&stream) { + bool isCompressed = stream->readUint32BE() == MKTAG('L', 'Z', 'V', 26); + stream->seek(-4, SEEK_CUR); + + if (isCompressed) { + Common::SeekableReadStream *newStream = decompressLZ(*stream); + delete stream; + stream = newStream; + } +} + /** * Loads a specific resource from a given library file */ @@ -207,6 +212,7 @@ Common::SeekableReadStream *Resources::load(const Common::String &filename, cons LibraryEntry &entry = _indexes[libraryFile][filename]; libStream->seek(entry._offset); Common::SeekableReadStream *stream = libStream->readStream(entry._size); + decompressIfNecessary(stream); delete libStream; return stream; diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h index d5e83a1745..6bb0682f8d 100644 --- a/engines/sherlock/resources.h +++ b/engines/sherlock/resources.h @@ -81,6 +81,8 @@ public: void addToCache(const Common::String &filename, Common::SeekableReadStream &stream); bool isInCache(const Common::String &filename) const { return _cache.isCached(filename); } + void decompressIfNecessary(Common::SeekableReadStream *&stream); + Common::SeekableReadStream *load(const Common::String &filename); Common::SeekableReadStream *load(const Common::String &filename, const Common::String &libraryFile); -- cgit v1.2.3 From 5e351b6bf3988b33a6af952331039083c3b2aff8 Mon Sep 17 00:00:00 2001 From: sirlemonhead Date: Sun, 17 May 2015 20:41:42 +0100 Subject: SHERLOCK: Replace scumm_stricmp() with equalsIgnoreCase() --- engines/sherlock/inventory.cpp | 10 +++++----- engines/sherlock/people.cpp | 2 +- engines/sherlock/saveload.cpp | 2 +- engines/sherlock/scene.cpp | 5 ++--- engines/sherlock/talk.cpp | 4 ++-- engines/sherlock/user_interface.cpp | 8 ++++---- 6 files changed, 15 insertions(+), 16 deletions(-) diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index 1997807d15..8da83aa5da 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -132,7 +132,7 @@ void Inventory::loadGraphics() { */ int Inventory::findInv(const Common::String &name) { for (int idx = 0; idx < (int)_names.size(); ++idx) { - if (scumm_stricmp(name.c_str(), _names[idx].c_str()) == 0) + if (name.equalsIgnoreCase(_names[idx])) return idx; } @@ -389,7 +389,7 @@ int Inventory::putNameInInventory(const Common::String &name) { for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) { Object &o = scene._bgShapes[idx]; - if (scumm_stricmp(name.c_str(), o._name.c_str()) == 0 && o._type != INVALID) { + if (name.equalsIgnoreCase(o._name) && o._type != INVALID) { putItemInInventory(o); ++matches; } @@ -411,13 +411,13 @@ int Inventory::putItemInInventory(Object &obj) { _vm->setFlags(obj._pickupFlag); for (int useNum = 0; useNum < 4; ++useNum) { - if (scumm_stricmp(obj._use[useNum]._target.c_str(), "*PICKUP*") == 0) { + if (obj._use[useNum]._target.equalsIgnoreCase("*PICKUP*")) { pickupFound = true; for (int namesNum = 0; namesNum < 4; ++namesNum) { for (uint bgNum = 0; bgNum < scene._bgShapes.size(); ++bgNum) { Object &bgObj = scene._bgShapes[bgNum]; - if (scumm_stricmp(obj._use[useNum]._names[namesNum].c_str(), bgObj._name.c_str()) == 0) { + if (obj._use[useNum]._names[namesNum].equalsIgnoreCase(bgObj._name)) { copyToInventory(bgObj); if (bgObj._pickupFlag) _vm->setFlags(bgObj._pickupFlag); @@ -485,7 +485,7 @@ int Inventory::deleteItemFromInventory(const Common::String &name) { int invNum = -1; for (int idx = 0; idx < (int)size() && invNum == -1; ++idx) { - if (scumm_stricmp(name.c_str(), (*this)[idx]._name.c_str()) == 0) + if (name.equalsIgnoreCase((*this)[idx]._name)) invNum = idx; } diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 0eda40c03f..9a42f94d4d 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -620,7 +620,7 @@ int People::findSpeaker(int speaker) { if (obj._type == ACTIVE_BG_SHAPE) { Common::String name(obj._name.c_str(), obj._name.c_str() + 4); - if (scumm_stricmp(PORTRAITS[speaker], name.c_str()) == 0 + if (name.equalsIgnoreCase(PORTRAITS[speaker]) && obj._name[4] >= '0' && obj._name[4] <= '9') return idx; } diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index b9ac3e79d6..0ac25a2f1a 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -441,7 +441,7 @@ bool SaveManager::getFilename(int slot) { screen.buttonPrint(Common::Point(ENV_POINTS[5][2], CONTROLS_Y), COMMAND_NULL, true, "Quit"); Common::String saveName = _savegames[slot]; - if (scumm_stricmp(saveName.c_str(), "-EMPTY-") == 0) { + if (saveName.equalsIgnoreCase("-EMPTY-")) { // It's an empty slot, so start off with an empty save name saveName = ""; diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 3dcfddd428..8a906e9335 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -617,8 +617,7 @@ void Scene::checkSceneFlags(bool flag) { void Scene::checkInventory() { for (uint shapeIdx = 0; shapeIdx < _bgShapes.size(); ++shapeIdx) { for (int invIdx = 0; invIdx < _vm->_inventory->_holdings; ++invIdx) { - if (scumm_stricmp(_bgShapes[shapeIdx]._name.c_str(), - (*_vm->_inventory)[invIdx]._name.c_str()) == 0) { + if (_bgShapes[shapeIdx]._name.equalsIgnoreCase((*_vm->_inventory)[invIdx]._name)) { _bgShapes[shapeIdx]._type = INVALID; break; } @@ -757,7 +756,7 @@ int Scene::toggleObject(const Common::String &name) { int count = 0; for (uint idx = 0; idx < _bgShapes.size(); ++idx) { - if (scumm_stricmp(name.c_str(), _bgShapes[idx]._name.c_str()) == 0) { + if (name.equalsIgnoreCase(_bgShapes[idx]._name)) { ++count; _bgShapes[idx].toggleHidden(); } diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index d656431823..b38b432e37 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1160,7 +1160,7 @@ void Talk::doScript(const Common::String &script) { // Scan for object int objId = -1; for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) { - if (scumm_stricmp(tempString.c_str(), scene._bgShapes[idx]._name.c_str()) == 0) + if (tempString.equalsIgnoreCase(scene._bgShapes[idx]._name)) objId = idx; } if (objId == -1) @@ -1372,7 +1372,7 @@ void Talk::doScript(const Common::String &script) { for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) { Object &object = scene._bgShapes[idx]; - if (scumm_stricmp(tempString.c_str(), object._name.c_str()) == 0) { + if (tempString.equalsIgnoreCase(object._name)) { // Only toggle the object if it's not in the desired state already if ((object._type == HIDDEN && state) || (object._type != HIDDEN && !state)) object.toggleHidden(); diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 1521421c15..d5ff828aee 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -2177,17 +2177,17 @@ void UserInterface::checkUseAction(const UseType *use, const Common::String &inv int targetNum = -1; if (giveMode) { for (int idx = 0; idx < 4 && targetNum == -1; ++idx) { - if ((scumm_stricmp(use[idx]._target.c_str(), "*GIVE*") == 0 || scumm_stricmp(use[idx]._target.c_str(), "*GIVEP*") == 0) - && scumm_stricmp(use[idx]._names[0].c_str(), invName.c_str()) == 0) { + if ((use[idx]._target.equalsIgnoreCase("*GIVE*") || use[idx]._target.equalsIgnoreCase("*GIVEP*")) + && use[idx]._names[0].equalsIgnoreCase(invName)) { // Found a match targetNum = idx; - if (scumm_stricmp(use[idx]._target.c_str(), "*GIVE*") == 0) + if (use[idx]._target.equalsIgnoreCase("*GIVE*")) inv.deleteItemFromInventory(invName); } } } else { for (int idx = 0; idx < 4 && targetNum == -1; ++idx) { - if (scumm_stricmp(use[idx]._target.c_str(), invName.c_str()) == 0) + if (use[idx]._target.equalsIgnoreCase(invName)) targetNum = idx; } } -- cgit v1.2.3 From f724cfcd22e4303d3c28dcca4e4789f5a21a09d6 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Sun, 17 May 2015 22:55:58 +0200 Subject: SHERLOCK: Skip a couple of cached files for interactive demo --- engines/sherlock/sound.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index 40aa4fa81a..e0552a8b5e 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -45,9 +45,12 @@ Sound::Sound(SherlockEngine *vm, Audio::Mixer *mixer): _vm(vm), _mixer(mixer) { _speechOn = true; _vm->_res->addToCache("MUSIC.LIB"); - _vm->_res->addToCache("TITLE.SND"); - _vm->_res->addToCache("EPILOGUE.SND"); _vm->_res->addToCache("SND.SND"); + + if (!_vm->getIsDemo()) { + _vm->_res->addToCache("TITLE.SND"); + _vm->_res->addToCache("EPILOGUE.SND"); + } } /** -- cgit v1.2.3 From f55ff7ba2184168bcbb3131a7ae978bc75032ff0 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 17 May 2015 17:21:21 -0400 Subject: SHERLOCK: Fix display of beveled background when entering Journal search --- engines/sherlock/journal.cpp | 6 ++---- engines/sherlock/screen.cpp | 14 +++++++++++++- engines/sherlock/screen.h | 1 + 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 2a7aeb4f2d..d510738da0 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -1033,9 +1033,7 @@ int Journal::getFindName(bool printError) { screen.makeButton(Common::Rect(SEARCH_POINTS[2][0], yp, SEARCH_POINTS[2][1], yp + 10), SEARCH_POINTS[2][2] - screen.stringWidth("Forward") / 2, "Forward"); - screen.gPrint(Common::Point(SEARCH_POINTS[0][2] - screen.stringWidth("Exit") / 2, yp), COMMAND_FOREGROUND, "E"); - screen.gPrint(Common::Point(SEARCH_POINTS[1][2] - screen.stringWidth("Backward") / 2, yp), COMMAND_FOREGROUND, "B"); - screen.gPrint(Common::Point(SEARCH_POINTS[2][2] - screen.stringWidth("Forward") / 2, yp), COMMAND_FOREGROUND, "F"); + screen.makeField(Common::Rect(12, 185, 307, 196)); screen.fillRect(Common::Rect(12, 185, 307, 186), BUTTON_BOTTOM); screen.vLine(12, 185, 195, BUTTON_BOTTOM); @@ -1160,7 +1158,7 @@ int Journal::getFindName(bool printError) { break; } } - } while (!done); + } while (!done && !_vm->shouldQuit()); if (done != -1) { _find = name; diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index cbf18f146f..c1c53fbe65 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -467,7 +467,7 @@ void Screen::buttonPrint(const Common::Point &pt, byte color, bool slamIt, } /** - * Draw a panel in th eback buffer with a raised area effect around the edges + * Draw a panel in the back buffer with a raised area effect around the edges */ void Screen::makePanel(const Common::Rect &r) { _backBuffer->fillRect(r, BUTTON_MIDDLE); @@ -482,6 +482,18 @@ void Screen::makePanel(const Common::Rect &r) { _backBuffer->hLine(r.left + 1, r.bottom - 2, r.right - 1, BUTTON_BOTTOM); } +/** + * Draw a field in the back buffer with a raised area effect around the edges, + * suitable for text input. + */ +void Screen::makeField(const Common::Rect &r) { + _backBuffer->fillRect(r, BUTTON_MIDDLE); + _backBuffer->hLine(r.left, r.top, r.right - 1, BUTTON_BOTTOM); + _backBuffer->hLine(r.left + 1, r.bottom - 1, r.right - 1, BUTTON_TOP); + _backBuffer->vLine(r.left, r.top + 1, r.bottom - 1, BUTTON_BOTTOM); + _backBuffer->vLine(r.right - 1, r.top + 1, r.bottom - 2, BUTTON_TOP); +} + /** * Sets the active back buffer pointer to a restricted sub-area of the first back buffer */ diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 1f3c23748f..2103588fe0 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -123,6 +123,7 @@ public: void buttonPrint(const Common::Point &pt, byte color, bool slamIt, const Common::String &str); void makePanel(const Common::Rect &r); + void makeField(const Common::Rect &r); void setDisplayBounds(const Common::Rect &r); void resetDisplayBounds(); -- cgit v1.2.3 From 12f260d66ea3443dd4b0c599c42d02ed7d0324d1 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 17 May 2015 17:33:42 -0400 Subject: SHERLOCK: Journal searches are uppercase --- engines/sherlock/journal.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index d510738da0..b9b66e74ad 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -1139,10 +1139,11 @@ int Journal::getFindName(bool printError) { if (keyState.keycode >= Common::KEYCODE_SPACE && keyState.keycode <= Common::KEYCODE_z && keyState.keycode != Common::KEYCODE_AT && name.size() < 50 && (xp + screen.charWidth(keyState.keycode)) < 296) { + char ch = toupper(keyState.keycode); screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), BUTTON_MIDDLE); - screen.print(Common::Point(xp, yp), TALK_FOREGROUND, "%c", (char)keyState.keycode); - xp += screen.charWidth((char)keyState.keycode); - name += (char)keyState.keycode; + screen.print(Common::Point(xp, yp), TALK_FOREGROUND, "%c", ch); + xp += screen.charWidth(ch); + name += ch; } } -- cgit v1.2.3 From 46c68176f8311ca9ae1e5982da4520de20830431 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 17 May 2015 17:50:13 -0400 Subject: SHERLOCK: Journal search buttons shouldn't have keyboard highlights --- engines/sherlock/journal.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index b9b66e74ad..9fad7bdfad 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -1032,6 +1032,12 @@ int Journal::getFindName(bool printError) { SEARCH_POINTS[1][2] - screen.stringWidth("Backward") / 2, "Backward"); screen.makeButton(Common::Rect(SEARCH_POINTS[2][0], yp, SEARCH_POINTS[2][1], yp + 10), SEARCH_POINTS[2][2] - screen.stringWidth("Forward") / 2, "Forward"); + screen.gPrint(Common::Point(SEARCH_POINTS[0][2] - screen.stringWidth("Exit") / 2, yp), + COMMAND_FOREGROUND, "E"); + screen.gPrint(Common::Point(SEARCH_POINTS[1][2] - screen.stringWidth("Backward") / 2, yp), + COMMAND_FOREGROUND, "B"); + screen.gPrint(Common::Point(SEARCH_POINTS[2][2] - screen.stringWidth("Forward") / 2, yp), + COMMAND_FOREGROUND, "F"); screen.makeField(Common::Rect(12, 185, 307, 196)); -- cgit v1.2.3 From b1b7ee33dfa3cf675f7c02daf825c0b0d277227d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 17 May 2015 18:02:49 -0400 Subject: SHERLOCK: Highlight found search matches in the journal --- engines/sherlock/journal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 9fad7bdfad..dc4ab9495f 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -562,7 +562,7 @@ bool Journal::drawJournal(int direction, int howFar) { int yp = 37; int startPage = _page; bool endJournal = false; - bool firstOccurance = false; + bool firstOccurance = true; bool searchSuccessful = false; bool endFlag = false; int lineNum = 0; -- cgit v1.2.3 From da9333a924d945c3bd59eb1f8d3dd17d86b5d572 Mon Sep 17 00:00:00 2001 From: sirlemonhead Date: Mon, 18 May 2015 18:20:54 +0100 Subject: SHERLOCK: Fix code formatting issues and comment spelling mistakes --- engines/sherlock/animation.cpp | 2 +- engines/sherlock/animation.h | 1 - engines/sherlock/detection.cpp | 6 +++--- engines/sherlock/inventory.cpp | 4 ++-- engines/sherlock/journal.cpp | 8 +++----- engines/sherlock/people.cpp | 4 ++-- engines/sherlock/people.h | 4 ++-- engines/sherlock/scene.cpp | 2 +- 8 files changed, 14 insertions(+), 17 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 1d6c12f668..6cdefaffbd 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -28,7 +28,7 @@ namespace Sherlock { static const int NO_FRAMES = FRAMES_END; -Animation::Animation(SherlockEngine *vm): _vm(vm) { +Animation::Animation(SherlockEngine *vm) : _vm(vm) { } /** diff --git a/engines/sherlock/animation.h b/engines/sherlock/animation.h index 06614df6b1..cd22a5c30a 100644 --- a/engines/sherlock/animation.h +++ b/engines/sherlock/animation.h @@ -44,7 +44,6 @@ private: Common::Array > _titleFrames; const int *checkForSoundFrames(const Common::String &filename); -public: public: Animation(SherlockEngine *vm); diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp index 2804ec1d31..00f6a1256e 100644 --- a/engines/sherlock/detection.cpp +++ b/engines/sherlock/detection.cpp @@ -66,7 +66,7 @@ static const ADExtraGuiOptionsMap optionsList[] = { GAMEOPTION_ORIGINAL_SAVES, { _s("Use original savegame dialog"), - _s("Files button in-game shows original savegame dialog rather than ScummVM menu"), + _s("Files button in-game shows original savegame dialog rather than the ScummVM menu"), "originalsaveload", false } @@ -197,7 +197,7 @@ SaveStateDescriptor SherlockMetaEngine::querySaveMetaInfos(const char *target, i #if PLUGIN_ENABLED_DYNAMIC(SHERLOCK) -REGISTER_PLUGIN_DYNAMIC(SHERLOCK, PLUGIN_TYPE_ENGINE, SherlockMetaEngine); + REGISTER_PLUGIN_DYNAMIC(SHERLOCK, PLUGIN_TYPE_ENGINE, SherlockMetaEngine); #else -REGISTER_PLUGIN_STATIC(SHERLOCK, PLUGIN_TYPE_ENGINE, SherlockMetaEngine); + REGISTER_PLUGIN_STATIC(SHERLOCK, PLUGIN_TYPE_ENGINE, SherlockMetaEngine); #endif diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index 8da83aa5da..5b548bb9e3 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -128,7 +128,7 @@ void Inventory::loadGraphics() { /** * Searches through the list of names that correspond to the inventory items - * and returns the numer that matches the passed name + * and returns the number that matches the passed name */ int Inventory::findInv(const Common::String &name) { for (int idx = 0; idx < (int)_names.size(); ++idx) { @@ -150,7 +150,7 @@ void Inventory::putInv(int slamIt) { UserInterface &ui = *_vm->_ui; // If an inventory item has disappeared (due to using it or giving it), - // a blank space slot may haave appeared. If so, adjust the inventory + // a blank space slot may have appeared. If so, adjust the inventory if (_invIndex > 0 && _invIndex > (_holdings - 6)) { --_invIndex; freeGraphics(); diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 2a7aeb4f2d..966ed55b81 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -248,7 +248,7 @@ void Journal::loadJournalFile(bool alreadyLoaded) { // Is it a control character? if (c < 128) { - // Nope. Set flag for allowing control coes to insert spaces + // Nope. Set flag for allowing control codes to insert spaces ctrlSpace = true; assert(c >= ' '); @@ -898,7 +898,6 @@ bool Journal::handleEvents(int key) { } screen.buttonPrint(Common::Point(JOURNAL_POINTS[7][2], JOURNAL_BUTTONS_Y + 11), color, true, "Last Page"); - // Print Text button if (pt.x > JOURNAL_POINTS[8][0] && pt.x < JOURNAL_POINTS[8][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) && pt.y < (JOURNAL_BUTTONS_Y + 20) && !_journal.empty()) { @@ -922,14 +921,14 @@ bool Journal::handleEvents(int key) { screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } - if (((found == BTN_UP && events._released) || key =='U') && _up) { + if (((found == BTN_UP && events._released) || key == 'U') && _up) { // Scroll up drawJournal(1, LINES_PER_PAGE); doArrows(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } - if (((found == BTN_DOWN && events._released) || key =='D') && _down) { + if (((found == BTN_DOWN && events._released) || key == 'D') && _down) { // Scroll down drawJournal(2, LINES_PER_PAGE); doArrows(); @@ -951,7 +950,6 @@ bool Journal::handleEvents(int key) { screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), COMMAND_FOREGROUND, true, "Search"); bool notFound = false; - do { int dir; if ((dir = getFindName(notFound)) != 0) { diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 9a42f94d4d..ad7c37a8c4 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -119,7 +119,7 @@ const char PORTRAITS[MAX_PEOPLE][5] = { { "INSP" } // Inspector Lestrade (Scotland Yard) }; -const char *const NAMES[MAX_PEOPLE] = { +const char *const NAMES[MAX_PEOPLE] = { "Sherlock Holmes", "Dr. Watson", "Inspector Lestrade", @@ -221,7 +221,7 @@ People::~People() { * Reset the player data */ void People::reset() { - // Note: The engine has theoretical support for two player charactersm but only the first one is used. + // Note: The engine has theoretical support for two player characters but only the first one is used. // Watson is, instead, handled by a different sprite in each scene, with a very simple initial movement, if any Sprite &p = _data[PLAYER]; diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index f98c3db867..9ac1a797c6 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -53,12 +53,12 @@ enum { MAP_DOWN = 5, MAP_DOWNLEFT = 6, MAP_LEFT = 2, MAP_UPLEFT = 8 }; -extern const char *const NAMES[MAX_PEOPLE]; +extern const char *const NAMES[MAX_PEOPLE]; extern const char PORTRAITS[MAX_PEOPLE][5]; class SherlockEngine; -class Person: public Sprite { +class Person : public Sprite { public: Person() : Sprite() {} diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 8a906e9335..41d9284024 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -964,7 +964,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) { if (talk._talkToAbort) return 1; - // Add new anim shape entry for displaying the animationo + // Add new anim shape entry for displaying the animation _canimShapes.push_back(Object()); Object &cObj = _canimShapes[_canimShapes.size() - 1]; -- cgit v1.2.3 From d82d476b277f80b69514fcb360ec47e9482e4a28 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Mon, 18 May 2015 20:57:27 +0200 Subject: SHERLOCK: Add code to make non-interactive demo completable --- engines/sherlock/journal.cpp | 6 ++++-- engines/sherlock/resources.cpp | 12 +++++++----- engines/sherlock/scalpel/scalpel.cpp | 10 +++++----- engines/sherlock/screen.cpp | 4 ++++ engines/sherlock/sherlock.cpp | 10 ++++++++++ engines/sherlock/sherlock.h | 1 + engines/sherlock/sound.cpp | 15 ++++++++++----- engines/sherlock/user_interface.cpp | 10 ++++++++-- 8 files changed, 49 insertions(+), 19 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index dc4ab9495f..3b63294b06 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -57,8 +57,10 @@ Journal::Journal(SherlockEngine *vm): _vm(vm) { _up = _down = false; _page = 1; - // Load the journal directory and location names - loadJournalLocations(); + if (_vm->_interactiveFl) { + // Load the journal directory and location names + loadJournalLocations(); + } } /** diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index f6fbded9b1..456006a86a 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -102,11 +102,13 @@ Common::SeekableReadStream *Cache::get(const Common::String &filename) const { Resources::Resources(SherlockEngine *vm): _vm(vm), _cache(vm) { _resourceIndex = -1; - addToCache("vgs.lib"); - addToCache("talk.lib"); - addToCache("sequence.txt"); - addToCache("journal.txt"); - addToCache("portrait.lib"); + if (_vm->_interactiveFl) { + addToCache("vgs.lib"); + addToCache("talk.lib"); + addToCache("sequence.txt"); + addToCache("journal.txt"); + addToCache("portrait.lib"); + } } /** diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 6959e435d2..078677be65 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -251,9 +251,9 @@ void ScalpelEngine::initialize() { _flags[39] = true; // Turn on Baker Street if (!getIsDemo()) { - // Load the map co-ordinates for each scene and sequence data - _map->loadPoints(NUM_PLACES, &MAP_X[0], &MAP_Y[0], &MAP_TRANSLATE[0]); - _map->loadSequences(3, &MAP_SEQUENCES[0][0]); + // Load the map co-ordinates for each scene and sequence data + _map->loadPoints(NUM_PLACES, &MAP_X[0], &MAP_Y[0], &MAP_TRANSLATE[0]); + _map->loadSequences(3, &MAP_SEQUENCES[0][0]); } // Load the inventory @@ -269,7 +269,7 @@ void ScalpelEngine::initialize() { _animation->setTitleFrames(&TITLE_FRAMES[0][0], 7, 9); // Starting scene - if (getIsDemo()) + if (getIsDemo() && _interactiveFl) _scene->_goToScene = 3; else _scene->_goToScene = 4; @@ -279,7 +279,7 @@ void ScalpelEngine::initialize() { * Show the opening sequence */ void ScalpelEngine::showOpening() { - if (getIsDemo()) + if (getIsDemo() && _interactiveFl) return; if (!showCityCutscene()) diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index c1c53fbe65..e98d9a51a9 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -53,6 +53,10 @@ Screen::~Screen() { * Set the font to use for writing text on the screen */ void Screen::setFont(int fontNumb) { + // Interactive demo doesn't use fonts + if (!_vm->_interactiveFl) + return; + _fontNumber = fontNumb; Common::String fname = Common::String::format("FONT%d.VGS", fontNumb + 1); diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 09a8ef18ef..5c7354e5f3 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -49,6 +49,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _loadGameSlot = -1; _canLoadSave = false; _showOriginalSavesDialog = false; + _interactiveFl = true; } SherlockEngine::~SherlockEngine() { @@ -79,6 +80,15 @@ void SherlockEngine::initialize() { ImageFile::setVm(this); Object::setVm(this); Sprite::setVm(this); + + if (getIsDemo()) { + Common::File f; + // The interactive demo doesn't have an intro thus doesn't include TITLE.SND + // At the opposite, the non-interactive demo is only the intro. + if (f.exists("TITLE.SND")) + _interactiveFl = false; + } + _res = new Resources(this); _animation = new Animation(this); _debugger = new Debugger(this); diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 33e4a45b40..bd6d4a4c8e 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -109,6 +109,7 @@ public: int _loadGameSlot; bool _canLoadSave; bool _showOriginalSavesDialog; + bool _interactiveFl; public: SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc); virtual ~SherlockEngine(); diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index e0552a8b5e..5199fe7dc4 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -44,12 +44,16 @@ Sound::Sound(SherlockEngine *vm, Audio::Mixer *mixer): _vm(vm), _mixer(mixer) { _musicOn = true; _speechOn = true; - _vm->_res->addToCache("MUSIC.LIB"); - _vm->_res->addToCache("SND.SND"); - - if (!_vm->getIsDemo()) { + if (!_vm->_interactiveFl) _vm->_res->addToCache("TITLE.SND"); - _vm->_res->addToCache("EPILOGUE.SND"); + else { + _vm->_res->addToCache("MUSIC.LIB"); + _vm->_res->addToCache("SND.SND"); + + if (!_vm->getIsDemo()) { + _vm->_res->addToCache("TITLE.SND"); + _vm->_res->addToCache("EPILOGUE.SND"); + } } } @@ -64,6 +68,7 @@ void Sound::syncSoundSettings() { void Sound::loadSound(const Common::String &name, int priority) { // No implementation required in ScummVM + warning("loadSound"); } static int8 creativeADPCM_ScaleMap[64] = { diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index d5ff828aee..e2ad307aa4 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -81,8 +81,14 @@ const char *const MUSE[] = { /*----------------------------------------------------------------*/ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { - _controls = new ImageFile("menu.all"); - _controlPanel = new ImageFile("controls.vgs"); + if (_vm->_interactiveFl) { + _controls = new ImageFile("menu.all"); + _controlPanel = new ImageFile("controls.vgs"); + } else { + _controls = nullptr; + _controlPanel = nullptr; + } + _bgFound = 0; _oldBgFound = -1; _keycode = Common::KEYCODE_INVALID; -- cgit v1.2.3 From c4513607473ed6889445b08ea4f77165df126854 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Mon, 18 May 2015 21:29:50 +0200 Subject: SHERLOCK: Make loop non-interactive demo (intro) --- engines/sherlock/sherlock.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 5c7354e5f3..bdd2ec3588 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -129,7 +129,9 @@ Common::Error SherlockEngine::run() { _saves->loadGame(_loadGameSlot); _loadGameSlot = -1; } else { - showOpening(); + do + showOpening(); + while (!shouldQuit() && !_interactiveFl); } while (!shouldQuit()) { -- cgit v1.2.3 From 0aebac9174f935e535b8e133efde43bd94be5b27 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Mon, 18 May 2015 23:23:37 +0200 Subject: SHERLOCK: Fix some issues pointed by LordHoto --- engines/sherlock/objects.h | 1 + engines/sherlock/scene.cpp | 10 +++++----- engines/sherlock/scene.h | 4 ++-- engines/sherlock/screen.cpp | 5 ++--- engines/sherlock/sherlock.h | 4 ---- engines/sherlock/sound.cpp | 2 +- engines/sherlock/talk.cpp | 2 +- 7 files changed, 12 insertions(+), 16 deletions(-) diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 4068973e58..7a1ef1aebe 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -164,6 +164,7 @@ struct UseType { void load(Common::SeekableReadStream &s); }; +enum { TURNON_OBJ = 0x20, TURNOFF_OBJ = 0x40 }; class Object { private: static SherlockEngine *_vm; diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 8a906e9335..fa5c5f439c 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -43,7 +43,7 @@ void BgFileHeader::load(Common::SeekableReadStream &s) { /** * Load the data for the object */ -void BgfileheaderInfo::load(Common::SeekableReadStream &s) { +void BgFileHeaderInfo::load(Common::SeekableReadStream &s) { _filesize = s.readUint32LE(); _maxFrames = s.readByte(); @@ -176,7 +176,7 @@ void Scene::selectScene() { _restoreFlag = true; events.clearEvents(); - // If there were any scripst waiting to be run, but were interrupt by a running + // If there were any scripts waiting to be run, but were interrupt by a running // canimation (probably the last scene's exit canim), clear the _scriptMoreFlag if (talk._scriptMoreFlag == 3) talk._scriptMoreFlag = 0; @@ -265,7 +265,7 @@ bool Scene::loadScene(const Common::String &filename) { _invGraphicItems = bgHeader._numImages + 1; // Read in the shapes header info - Common::Array bgInfo; + Common::Array bgInfo; bgInfo.resize(bgHeader._numStructs); for (uint idx = 0; idx < bgInfo.size(); ++idx) @@ -461,13 +461,13 @@ bool Scene::loadScene(const Common::String &filename) { // Check for TURNON objects for (uint idx = 0; idx < _bgShapes.size(); ++idx) { - if (_bgShapes[idx]._type == HIDDEN && (_bgShapes[idx]._flags & 0x20)) + if (_bgShapes[idx]._type == HIDDEN && (_bgShapes[idx]._flags & TURNON_OBJ)) _bgShapes[idx].toggleHidden(); } // Check for TURNOFF objects for (uint idx = 0; idx < _bgShapes.size(); ++idx) { - if (_bgShapes[idx]._type != HIDDEN && (_bgShapes[idx]._flags & 0x40) && + if (_bgShapes[idx]._type != HIDDEN && (_bgShapes[idx]._flags & TURNOFF_OBJ) && _bgShapes[idx]._type != INVALID) _bgShapes[idx].toggleHidden(); if (_bgShapes[idx]._type == HIDE_SHAPE) diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 665f5d28e4..78d41299e6 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -49,7 +49,7 @@ struct BgFileHeader { void load(Common::SeekableReadStream &s); }; -struct BgfileheaderInfo { +struct BgFileHeaderInfo { int _filesize; // How long images are int _maxFrames; // How many unique frames in object Common::String _filename; // Filename of object @@ -83,7 +83,7 @@ struct SceneSound { void load(Common::SeekableReadStream &s); }; -class ObjectArray: public Common::Array { +class ObjectArray : public Common::Array { public: int indexOf(const Object &obj) const; }; diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index e98d9a51a9..d9ec1d745d 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -116,8 +116,7 @@ int Screen::equalizePalette(const byte palette[PALETTE_SIZE]) { // For any palette component that doesn't already match the given destination // palette, change by 1 towards the reference palette component for (int idx = 0; idx < PALETTE_SIZE; ++idx) { - if (tempPalette[idx] > palette[idx]) - { + if (tempPalette[idx] > palette[idx]) { tempPalette[idx] = MAX((int)palette[idx], (int)tempPalette[idx] - 4); ++total; } else if (tempPalette[idx] < palette[idx]) { @@ -216,7 +215,7 @@ void Screen::randomTransition() { for (int idx = 0; idx <= 65535 && !_vm->shouldQuit(); ++idx) { _transitionSeed = _transitionSeed * TRANSITION_MULTIPLIER + 1; - int offset = _transitionSeed & 65535; + int offset = _transitionSeed & 0xFFFF; if (offset < (SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCREEN_HEIGHT)) *((byte *)getPixels() + offset) = *((const byte *)_backBuffer->getPixels() + offset); diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index bd6d4a4c8e..68c8e8daca 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -49,10 +49,6 @@ namespace Sherlock { -enum { - kFileTypeHash -}; - enum { kDebugScript = 1 << 0 }; diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index 5199fe7dc4..c79e179c1c 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -89,7 +89,7 @@ static uint8 creativeADPCM_AdjustMap[64] = { 240, 0, 0, 0, 0, 0, 0, 0 }; -byte Sound::decodeSample(byte sample, byte& reference, int16& scale) { +byte Sound::decodeSample(byte sample, byte &reference, int16 &scale) { int16 samp = sample + scale; int16 ref = 0; diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index b38b432e37..dfcf9b912d 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -672,7 +672,7 @@ void Talk::drawInterface() { } /** - * Display a list of statements in a window at the bottom of the scren that the + * Display a list of statements in a window at the bottom of the screen that the * player can select from. */ bool Talk::displayTalk(bool slamIt) { -- cgit v1.2.3 From 0b50a077f7ef1308f3da8a0e6ac29e5bdff78c99 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 May 2015 18:12:58 -0400 Subject: SHERLOCK: Fix spacing in constructors --- engines/sherlock/journal.cpp | 2 +- engines/sherlock/map.cpp | 2 +- engines/sherlock/resources.cpp | 4 ++-- engines/sherlock/scene.cpp | 2 +- engines/sherlock/sound.cpp | 2 +- engines/sherlock/surface.cpp | 2 +- engines/sherlock/talk.cpp | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 7e0120c67d..f288b43650 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -49,7 +49,7 @@ const int SEARCH_POINTS[3][3] = { /*----------------------------------------------------------------*/ -Journal::Journal(SherlockEngine *vm): _vm(vm) { +Journal::Journal(SherlockEngine *vm) : _vm(vm) { // Initialize fields _maxPage = 0; _index = 0; diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index 7fca4ea5f3..dc9a0565cb 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -52,7 +52,7 @@ const byte *MapPaths::getPath(int srcLocation, int destLocation) { /*----------------------------------------------------------------*/ -Map::Map(SherlockEngine *vm): _vm(vm), _topLine(SHERLOCK_SCREEN_WIDTH, 12) { +Map::Map(SherlockEngine *vm) : _vm(vm), _topLine(SHERLOCK_SCREEN_WIDTH, 12) { _active = false; _mapCursors = nullptr; _shapes = nullptr; diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index 456006a86a..fa68074c60 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -28,7 +28,7 @@ namespace Sherlock { -Cache::Cache(SherlockEngine *vm): _vm(vm) { +Cache::Cache(SherlockEngine *vm) : _vm(vm) { } /** @@ -99,7 +99,7 @@ Common::SeekableReadStream *Cache::get(const Common::String &filename) const { /*----------------------------------------------------------------*/ -Resources::Resources(SherlockEngine *vm): _vm(vm), _cache(vm) { +Resources::Resources(SherlockEngine *vm) : _vm(vm), _cache(vm) { _resourceIndex = -1; if (_vm->_interactiveFl) { diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index a65c11b167..91c411db88 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -111,7 +111,7 @@ int ObjectArray::indexOf(const Object &obj) const { /*----------------------------------------------------------------*/ -Scene::Scene(SherlockEngine *vm): _vm(vm) { +Scene::Scene(SherlockEngine *vm) : _vm(vm) { for (int idx = 0; idx < SCENES_COUNT; ++idx) Common::fill(&_sceneStats[idx][0], &_sceneStats[idx][65], false); _currentScene = -1; diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index c79e179c1c..3270fbf7e4 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -30,7 +30,7 @@ namespace Sherlock { -Sound::Sound(SherlockEngine *vm, Audio::Mixer *mixer): _vm(vm), _mixer(mixer) { +Sound::Sound(SherlockEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) { _digitized = false; _music = false; _voices = 0; diff --git a/engines/sherlock/surface.cpp b/engines/sherlock/surface.cpp index 36e625794c..eeaf304958 100644 --- a/engines/sherlock/surface.cpp +++ b/engines/sherlock/surface.cpp @@ -27,7 +27,7 @@ namespace Sherlock { -Surface::Surface(uint16 width, uint16 height): _freePixels(true) { +Surface::Surface(uint16 width, uint16 height) : _freePixels(true) { create(width, height); } diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index dfcf9b912d..dc5b9c5ba7 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -91,7 +91,7 @@ void TalkSequences::clear() { /*----------------------------------------------------------------*/ -Talk::Talk(SherlockEngine *vm): _vm(vm) { +Talk::Talk(SherlockEngine *vm) : _vm(vm) { _talkCounter = 0; _talkToAbort = false; _speaker = 0; -- cgit v1.2.3 From c24d0de8f6147ef31e015a3e642fcb1896013b50 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 May 2015 18:21:41 -0400 Subject: SHERLOCK: Remove unused variable --- engines/sherlock/animation.cpp | 2 -- engines/sherlock/sound.cpp | 1 - engines/sherlock/sound.h | 1 - 3 files changed, 4 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 6cdefaffbd..3c7b2b7443 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -40,7 +40,6 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade, Screen &screen = *_vm->_screen; Sound &sound = *_vm->_sound; int soundNumber = 0; - sound._playingEpilogue = true; // Check for any any sound frames for the given animation const int *soundFrames = checkForSoundFrames(filename); @@ -133,7 +132,6 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade, events.clearEvents(); sound.stopSound(); delete stream; - sound._playingEpilogue = false; return !skipped && !_vm->shouldQuit(); } diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index 3270fbf7e4..b44eb17397 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -34,7 +34,6 @@ Sound::Sound(SherlockEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) { _digitized = false; _music = false; _voices = 0; - _playingEpilogue = false; _diskSoundPlaying = false; _soundPlaying = false; _soundIsOn = &_soundPlaying; diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index 4d94c58f6f..62d4aa24c4 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -54,7 +54,6 @@ public: bool _soundOn; bool _musicOn; bool _speechOn; - bool _playingEpilogue; bool _diskSoundPlaying; bool _soundPlaying; bool *_soundIsOn; -- cgit v1.2.3 From 844d8012598bf1f43b7eff4c8d7b9a7be9287b18 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 May 2015 18:30:31 -0400 Subject: SHERLOCK: Syntactic fixes --- engines/sherlock/animation.cpp | 8 ++++---- engines/sherlock/detection.cpp | 2 +- engines/sherlock/detection_tables.h | 2 +- engines/sherlock/inventory.cpp | 3 ++- engines/sherlock/map.cpp | 2 +- engines/sherlock/scalpel/scalpel.cpp | 6 +++--- engines/sherlock/scene.cpp | 2 +- engines/sherlock/sherlock.cpp | 2 +- engines/sherlock/sherlock.h | 2 +- engines/sherlock/sound.cpp | 2 +- 10 files changed, 16 insertions(+), 15 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 3c7b2b7443..3c283636ca 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -140,7 +140,7 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade, * Load the prologue name array */ void Animation::setPrologueNames(const char *const *names, int count) { - for (int idx = 0; idx < count; ++idx, names++) { + for (int idx = 0; idx < count; ++idx, ++names) { _prologueNames.push_back(*names); } } @@ -161,7 +161,7 @@ void Animation::setPrologueFrames(const int *frames, int count, int maxFrames) { * Load the title name array */ void Animation::setTitleNames(const char *const *names, int count) { - for (int idx = 0; idx < count; ++idx, names++) { + for (int idx = 0; idx < count; ++idx, ++names) { _titleNames.push_back(*names); } } @@ -185,14 +185,14 @@ const int *Animation::checkForSoundFrames(const Common::String &filename) { const int *frames = &NO_FRAMES; if (_vm->_soundOverride.empty()) { - for (Common::Array::size_type idx = 0; idx < _prologueNames.size(); ++idx) { + for (uint idx = 0; idx < _prologueNames.size(); ++idx) { if (filename.equalsIgnoreCase(_prologueNames[idx])) { frames = &_prologueFrames[idx][0]; break; } } } else { - for (Common::Array::size_type idx = 0; idx < _titleNames.size(); ++idx) { + for (uint idx = 0; idx < _titleNames.size(); ++idx) { if (filename.equalsIgnoreCase(_titleNames[idx])) { frames = &_titleFrames[idx][0]; break; diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp index 00f6a1256e..e69887b5c7 100644 --- a/engines/sherlock/detection.cpp +++ b/engines/sherlock/detection.cpp @@ -144,7 +144,7 @@ bool Sherlock::SherlockEngine::hasFeature(EngineFeature f) const { /** * Returns whether the version is a demo */ -bool Sherlock::SherlockEngine::getIsDemo() const { +bool Sherlock::SherlockEngine::isDemo() const { return _gameDescription->desc.flags & ADGF_DEMO; } diff --git a/engines/sherlock/detection_tables.h b/engines/sherlock/detection_tables.h index 8300a0ffcf..3960836f82 100644 --- a/engines/sherlock/detection_tables.h +++ b/engines/sherlock/detection_tables.h @@ -32,7 +32,7 @@ static const SherlockGameDescription gameDescriptions[] = { AD_ENTRY1s("talk.lib", "ad0c4d6865edf15da4e9204c08815875", 238928), Common::EN_ANY, Common::kPlatformDOS, - ADGF_UNSTABLE | ADGF_NO_FLAGS, + ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GAMEOPTION_ORIGINAL_SAVES) }, GType_SerratedScalpel, diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index 5b548bb9e3..b7d973e289 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -136,7 +136,8 @@ int Inventory::findInv(const Common::String &name) { return idx; } - return 1; + // Couldn't find the desired item + error("Couldn't find inventory item - %s", name.c_str()); } /** diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index dc9a0565cb..36c932d90d 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -69,7 +69,7 @@ Map::Map(SherlockEngine *vm) : _vm(vm), _topLine(SHERLOCK_SCREEN_WIDTH, 12) { for (int idx = 0; idx < MAX_HOLMES_SEQUENCE; ++idx) Common::fill(&_sequences[idx][0], &_sequences[idx][MAX_FRAME], 0); - if (!_vm->getIsDemo()) + if (!_vm->isDemo()) loadData(); } diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 078677be65..0d62336283 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -250,7 +250,7 @@ void ScalpelEngine::initialize() { _flags[3] = true; // Turn on Alley _flags[39] = true; // Turn on Baker Street - if (!getIsDemo()) { + if (!isDemo()) { // Load the map co-ordinates for each scene and sequence data _map->loadPoints(NUM_PLACES, &MAP_X[0], &MAP_Y[0], &MAP_TRANSLATE[0]); _map->loadSequences(3, &MAP_SEQUENCES[0][0]); @@ -269,7 +269,7 @@ void ScalpelEngine::initialize() { _animation->setTitleFrames(&TITLE_FRAMES[0][0], 7, 9); // Starting scene - if (getIsDemo() && _interactiveFl) + if (isDemo() && _interactiveFl) _scene->_goToScene = 3; else _scene->_goToScene = 4; @@ -279,7 +279,7 @@ void ScalpelEngine::initialize() { * Show the opening sequence */ void ScalpelEngine::showOpening() { - if (getIsDemo() && _interactiveFl) + if (isDemo() && _interactiveFl) return; if (!showCityCutscene()) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 91c411db88..b75531baf6 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -495,7 +495,7 @@ bool Scene::loadScene(const Common::String &filename) { _walkedInScene = false; saves._justLoaded = false; - if (!_vm->getIsDemo()) { + if (!_vm->isDemo()) { // Reset the previous map location and position on overhead map map._oldCharPoint = _currentScene; map._overPos.x = map[_currentScene].x * 100 - 600; diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index bdd2ec3588..eb80fb6e3b 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -81,7 +81,7 @@ void SherlockEngine::initialize() { Object::setVm(this); Sprite::setVm(this); - if (getIsDemo()) { + if (isDemo()) { Common::File f; // The interactive demo doesn't have an intro thus doesn't include TITLE.SND // At the opposite, the non-interactive demo is only the intro. diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 68c8e8daca..571bd4dc61 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -117,7 +117,7 @@ public: virtual Common::Error loadGameState(int slot); virtual Common::Error saveGameState(int slot, const Common::String &desc); virtual void syncSoundSettings(); - virtual bool getIsDemo() const; + virtual bool isDemo() const; GameType getGameID() const; Common::Language getLanguage() const; diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index b44eb17397..bcc6c96e4f 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -49,7 +49,7 @@ Sound::Sound(SherlockEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) { _vm->_res->addToCache("MUSIC.LIB"); _vm->_res->addToCache("SND.SND"); - if (!_vm->getIsDemo()) { + if (!_vm->isDemo()) { _vm->_res->addToCache("TITLE.SND"); _vm->_res->addToCache("EPILOGUE.SND"); } -- cgit v1.2.3 From 34227d1b545b12471341ae35e4b6a5c23bfa6338 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 May 2015 18:34:10 -0400 Subject: SHERLOCK: Simplify Events::getKey --- engines/sherlock/events.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index 3b0b0dacc6..7f57625a3b 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -198,11 +198,7 @@ bool Events::checkForNextFrameCounter() { * Get a pending keypress */ Common::KeyState Events::getKey() { - Common::KeyState keyState = _pendingKeys.pop(); - if ((keyState.flags & Common::KBD_SHIFT) != 0) - keyState.ascii = toupper(keyState.ascii); - - return keyState; + return _pendingKeys.pop(); } /** -- cgit v1.2.3 From 437bcf3cfe4aabe99359d3b6db3cd8e13f3e8763 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 May 2015 18:43:29 -0400 Subject: SHERLOCK: Simplify Events not to need it's own copy of the mouse pos --- engines/sherlock/events.cpp | 10 +++++++--- engines/sherlock/events.h | 3 +-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index 7f57625a3b..84794e6e6a 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -154,9 +154,6 @@ void Events::pollEvents() { case Common::EVENT_RBUTTONUP: _mouseButtons &= ~2; return; - case Common::EVENT_MOUSEMOVE: - _mousePos = event.mouse; - break; default: break; } @@ -194,6 +191,13 @@ bool Events::checkForNextFrameCounter() { return false; } +/** + * Get the current mouse position + */ +Common::Point Events::mousePos() const { + return g_system->getEventManager()->getMousePos(); +} + /** * Get a pending keypress */ diff --git a/engines/sherlock/events.h b/engines/sherlock/events.h index 199e14f03a..c6d155e472 100644 --- a/engines/sherlock/events.h +++ b/engines/sherlock/events.h @@ -42,7 +42,6 @@ private: SherlockEngine *_vm; uint32 _frameCounter; uint32 _priorFrameTime; - Common::Point _mousePos; ImageFile *_cursorImages; int _mouseButtons; @@ -79,7 +78,7 @@ public: void pollEventsAndWait(); - Common::Point mousePos() const { return _mousePos; } + Common::Point mousePos() const; uint32 getFrameCounter() const { return _frameCounter; } -- cgit v1.2.3 From 46293735c4e10d654d6195fce7781782f1024b26 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 May 2015 18:52:20 -0400 Subject: SHERLOCK: Remove some redundant fields from UseType --- engines/sherlock/objects.cpp | 6 +----- engines/sherlock/objects.h | 2 -- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index b4371cd71b..05a058a3bb 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -386,8 +386,6 @@ void ActionType::load(Common::SeekableReadStream &s) { UseType::UseType() { _cAnimNum = _cAnimSpeed = 0; _useFlag = 0; - _dFlag[0] = 0; - _lFlag[0] = _lFlag[1] = 0; } /** @@ -407,9 +405,7 @@ void UseType::load(Common::SeekableReadStream &s) { } _useFlag = s.readSint16LE(); - _dFlag[0] = s.readSint16LE(); - _lFlag[0] = s.readSint16LE(); - _lFlag[1] = s.readSint16LE(); + s.skip(6); s.read(buffer, 12); _target = Common::String(buffer); diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 7a1ef1aebe..4e7b006844 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -156,8 +156,6 @@ struct UseType { int _cAnimSpeed; Common::String _names[4]; int _useFlag; // Which flag USE will set (if any) - int _dFlag[1]; - int _lFlag[2]; Common::String _target; UseType(); -- cgit v1.2.3 From 59993fdc74afad7b210da7849f8ce25631153201 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 May 2015 19:15:17 -0400 Subject: SHERLOCK: Replace magic numbers with enums and constants --- engines/sherlock/inventory.cpp | 46 +++++++++++++++---------------------- engines/sherlock/inventory.h | 12 ++++++++-- engines/sherlock/objects.cpp | 18 +++++++-------- engines/sherlock/objects.h | 9 +++++--- engines/sherlock/scalpel/darts.cpp | 9 ++++---- engines/sherlock/scene.cpp | 4 ++-- engines/sherlock/user_interface.cpp | 34 +++++++++++++-------------- 7 files changed, 68 insertions(+), 64 deletions(-) diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index b7d973e289..283164c534 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -142,11 +142,8 @@ int Inventory::findInv(const Common::String &name) { /** * Display the character's inventory. The slamIt parameter specifies: - * 0 = Draw it on the back buffer, and don't display it - * 1 = Draw it on the back buffer, and then display it - * 2 = Draw it on the secondary back buffer, and don't display it */ -void Inventory::putInv(int slamIt) { +void Inventory::putInv(InvSlamMode slamIt) { Screen &screen = *_vm->_screen; UserInterface &ui = *_vm->_ui; @@ -158,7 +155,7 @@ void Inventory::putInv(int slamIt) { loadGraphics(); } - if (slamIt != 2) { + if (slamIt != SLAM_SECONDARY_BUFFER) { screen.makePanel(Common::Rect(6, 163, 54, 197)); screen.makePanel(Common::Rect(58, 163, 106, 197)); screen.makePanel(Common::Rect(110, 163, 158, 197)); @@ -170,13 +167,13 @@ void Inventory::putInv(int slamIt) { // Iterate through displaying up to 6 objects at a time for (int idx = _invIndex; idx < _holdings && (idx - _invIndex) < MAX_VISIBLE_INVENTORY; ++idx) { int itemNum = idx - _invIndex; - Surface &bb = slamIt == 2 ? screen._backBuffer2 : screen._backBuffer1; + Surface &bb = slamIt == SLAM_SECONDARY_BUFFER ? screen._backBuffer2 : screen._backBuffer1; Common::Rect r(8 + itemNum * 52, 165, 51 + itemNum * 52, 194); // Draw the background if (idx == ui._selector) { bb.fillRect(r, 235); - } else if (slamIt == 2) { + } else if (slamIt == SLAM_SECONDARY_BUFFER) { bb.fillRect(r, BUTTON_MIDDLE); } @@ -186,15 +183,15 @@ void Inventory::putInv(int slamIt) { 163 + ((33 - img.h) / 2))); } - if (slamIt == 1) + if (slamIt == SLAM_DISPLAY) screen.slamArea(6, 163, 308, 34); - if (slamIt != 2) + if (slamIt != SLAM_SECONDARY_BUFFER) ui.clearInfo(); if (slamIt == 0) { invCommands(0); - } else if (slamIt == 2) { + } else if (slamIt == SLAM_SECONDARY_BUFFER) { screen._backBuffer = &screen._backBuffer2; invCommands(0); screen._backBuffer = &screen._backBuffer1; @@ -203,20 +200,15 @@ void Inventory::putInv(int slamIt) { /** * Put the game into inventory mode and open the interface window. - * The flag parameter specifies the mode: - * 0 = plain inventory mode - * 2 = use inventory mode - * 3 = give inventory mode - * 128 = Draw window in the back buffer, but don't display it */ -void Inventory::drawInventory(int flag) { +void Inventory::drawInventory(InvNewMode mode) { Screen &screen = *_vm->_screen; UserInterface &ui = *_vm->_ui; - int tempFlag = flag; + InvNewMode tempMode = mode; loadInv(); - if (flag == 128) { + if (mode == INVENTORY_DONT_DISPLAY) { screen._backBuffer = &screen._backBuffer2; } @@ -249,20 +241,20 @@ void Inventory::drawInventory(int flag) { screen.makeButton(Common::Rect(INVENTORY_POINTS[7][0], CONTROLS_Y1, INVENTORY_POINTS[7][1], CONTROLS_Y1 + 10), INVENTORY_POINTS[7][2], "__"); - if (tempFlag == 128) - flag = 1; - _invMode = (InvMode)flag; + if (tempMode == INVENTORY_DONT_DISPLAY) + mode = LOOK_INVENTORY_MODE; + _invMode = (InvMode)mode; - if (flag) { - ui._oldKey = INVENTORY_COMMANDS[flag]; + if (mode != PLAIN_INVENTORY) { + ui._oldKey = INVENTORY_COMMANDS[(int)mode]; } else { ui._oldKey = -1; } invCommands(0); - putInv(0); + putInv(SLAM_DONT_DISPLAY); - if (tempFlag != 128) { + if (tempMode != INVENTORY_DONT_DISPLAY) { if (!ui._windowStyle) { screen.slamRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); } else { @@ -411,11 +403,11 @@ int Inventory::putItemInInventory(Object &obj) { if (obj._pickupFlag) _vm->setFlags(obj._pickupFlag); - for (int useNum = 0; useNum < 4; ++useNum) { + for (int useNum = 0; useNum < USE_COUNT; ++useNum) { if (obj._use[useNum]._target.equalsIgnoreCase("*PICKUP*")) { pickupFound = true; - for (int namesNum = 0; namesNum < 4; ++namesNum) { + for (int namesNum = 0; namesNum < NAMES_COUNT; ++namesNum) { for (uint bgNum = 0; bgNum < scene._bgShapes.size(); ++bgNum) { Object &bgObj = scene._bgShapes[bgNum]; if (obj._use[useNum]._names[namesNum].equalsIgnoreCase(bgObj._name)) { diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index eb5aebdd7c..979507a387 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -47,6 +47,14 @@ enum InvMode { INVMODE_USE55 = 255 }; +enum InvNewMode { + PLAIN_INVENTORY = 0, LOOK_INVENTORY_MODE = 1, USE_INVENTORY_MODE = 2, + GIVE_INVENTORY_MODE = 3, INVENTORY_DONT_DISPLAY = 128 +}; + +enum InvSlamMode { SLAM_DONT_DISPLAY, SLAM_DISPLAY = 1, SLAM_SECONDARY_BUFFER }; + + struct InventoryItem { int _requiredFlag; Common::String _name; @@ -87,9 +95,9 @@ public: int findInv(const Common::String &name); - void putInv(int slamIt); + void putInv(InvSlamMode slamIt); - void drawInventory(int flag); + void drawInventory(InvNewMode flag); void invCommands(bool slamIt); diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 05a058a3bb..310afbf94b 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -375,7 +375,7 @@ void ActionType::load(Common::SeekableReadStream &s) { if (_cAnimSpeed & 0x80) _cAnimSpeed = -(_cAnimSpeed & 0x7f); - for (int idx = 0; idx < 4; ++idx) { + for (int idx = 0; idx < NAMES_COUNT; ++idx) { s.read(buffer, 12); _names[idx] = Common::String(buffer); } @@ -399,7 +399,7 @@ void UseType::load(Common::SeekableReadStream &s) { if (_cAnimSpeed & 0x80) _cAnimSpeed = -(_cAnimSpeed & 0x7f); - for (int idx = 0; idx < 4; ++idx) { + for (int idx = 0; idx < NAMES_COUNT; ++idx) { s.read(buffer, 12); _names[idx] = Common::String(buffer); } @@ -518,7 +518,7 @@ void Object::load(Common::SeekableReadStream &s) { _aMove.load(s); s.skip(8); - for (int idx = 0; idx < 4; ++idx) + for (int idx = 0; idx < USE_COUNT; ++idx) _use[idx].load(s); } @@ -671,8 +671,8 @@ void Object::checkObject() { _delta = pt; _frameNumber += 2; - } else if (v < 4) { - for (int idx = 0; idx < 4; ++idx) { + } else if (v < USE_COUNT) { + for (int idx = 0; idx < NAMES_COUNT; ++idx) { checkNameForCodes(_use[v]._names[idx], nullptr); } @@ -928,7 +928,7 @@ void Object::setFlagsAndToggles() { Scene &scene = *_vm->_scene; Talk &talk = *_vm->_talk; - for (int useIdx = 0; useIdx < 4; ++useIdx) { + for (int useIdx = 0; useIdx < USE_COUNT; ++useIdx) { if (_use[useIdx]._useFlag) { if (!_vm->readFlags(_use[useIdx]._useFlag)) _vm->setFlags(_use[useIdx]._useFlag); @@ -943,7 +943,7 @@ void Object::setFlagsAndToggles() { } if (!talk._talkToAbort) { - for (int idx = 0; idx < 4; ++idx) + for (int idx = 0; idx < NAMES_COUNT; ++idx) scene.toggleObject(_use[useIdx]._names[idx]); } } @@ -991,7 +991,7 @@ int Object::pickUpObject(const char *const messages[]) { int numObjects = 0; if (pickup == 99) { - for (int idx = 0; idx < 4 && !talk._talkToAbort; ++idx) { + for (int idx = 0; idx < NAMES_COUNT && !talk._talkToAbort; ++idx) { if (checkNameForCodes(_use[0]._names[idx], nullptr)) { if (!talk._talkToAbort) printed = true; @@ -1038,7 +1038,7 @@ int Object::pickUpObject(const char *const messages[]) { ui._temp1 = 1; } - for (int idx = 0; idx < 4 && !talk._talkToAbort; ++idx) { + for (int idx = 0; idx < NAMES_COUNT && !talk._talkToAbort; ++idx) { if (checkNameForCodes(_use[0]._names[idx], nullptr)) { if (!talk._talkToAbort) printed = true; diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 4e7b006844..0b3a26f1f9 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -142,11 +142,12 @@ public: }; enum { REVERSE_DIRECTION = 0x80 }; +#define NAMES_COUNT 4 struct ActionType { int _cAnimNum; int _cAnimSpeed; - Common::String _names[4]; + Common::String _names[NAMES_COUNT]; void load(Common::SeekableReadStream &s); }; @@ -154,7 +155,7 @@ struct ActionType { struct UseType { int _cAnimNum; int _cAnimSpeed; - Common::String _names[4]; + Common::String _names[NAMES_COUNT]; int _useFlag; // Which flag USE will set (if any) Common::String _target; @@ -163,6 +164,8 @@ struct UseType { }; enum { TURNON_OBJ = 0x20, TURNOFF_OBJ = 0x40 }; +#define USE_COUNT 4 + class Object { private: static SherlockEngine *_vm; @@ -217,7 +220,7 @@ public: int _seqCounter2; // Counter of calling frame sequence uint _seqSize; // Tells where description starts ActionType _aMove; - UseType _use[4]; + UseType _use[USE_COUNT]; Object(); diff --git a/engines/sherlock/scalpel/darts.cpp b/engines/sherlock/scalpel/darts.cpp index 6da8d6848e..29b67216b9 100644 --- a/engines/sherlock/scalpel/darts.cpp +++ b/engines/sherlock/scalpel/darts.cpp @@ -44,9 +44,10 @@ enum { DART_COL_FORE = 5, PLAYER_COLOR = 11 }; +#define OPPONENTS_COUNT 4 -const char *const OPPONENT_NAMES[5] = { - "Skipper", "Willy", "Micky", "Tom", "Bartender" +const char *const OPPONENT_NAMES[OPPONENTS_COUNT] = { + "Skipper", "Willy", "Micky", "Tom" }; /*----------------------------------------------------------------*/ @@ -118,7 +119,7 @@ void Darts::playDarts() { if (playerNumber == 0) { screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 30), PLAYER_COLOR, "Holmes Wins!"); - if (_level < 4) + if (_level < OPPONENTS_COUNT) setFlagsForDarts(318 + _level); } else { screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 30), PLAYER_COLOR, "%s Wins!", _opponent.c_str()); @@ -210,7 +211,7 @@ void Darts::initDarts() { _computerPlayer = 2; } else { // Check flags for opponents - for (int idx = 0; idx < 4; ++idx) { + for (int idx = 0; idx < OPPONENTS_COUNT; ++idx) { if (_vm->readFlags(314 + idx)) _level = idx; } diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index b75531baf6..b092bbce65 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -706,14 +706,14 @@ void Scene::transitionToScene() { // player is clear of the box switch (obj._aType) { case FLAG_SET: - for (int useNum = 0; useNum < 4; ++useNum) { + for (int useNum = 0; useNum < USE_COUNT; ++useNum) { if (obj._use[useNum]._useFlag) { if (!_vm->readFlags(obj._use[useNum]._useFlag)) _vm->setFlags(obj._use[useNum]._useFlag); } if (!talk._talkToAbort) { - for (int nameIdx = 0; nameIdx < 4; ++nameIdx) { + for (int nameIdx = 0; nameIdx < NAMES_COUNT; ++nameIdx) { toggleObject(obj._use[useNum]._names[nameIdx]); } } diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index e2ad307aa4..ffcbddb920 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1156,7 +1156,7 @@ void UserInterface::doInvControl() { COMMAND_HIGHLIGHTED, "^^"); inv.freeGraphics(); inv.loadGraphics(); - inv.putInv(1); + inv.putInv(SLAM_DISPLAY); inv.invCommands(true); } else if (((found == 5 && events._released) || _key == Common::KEYCODE_MINUS || _key == Common::KEYCODE_KP_MINUS) && inv._invIndex > 0) { @@ -1164,7 +1164,7 @@ void UserInterface::doInvControl() { screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1), COMMAND_HIGHLIGHTED, "^"); inv.freeGraphics(); inv.loadGraphics(); - inv.putInv(1); + inv.putInv(SLAM_DISPLAY); inv.invCommands(true); } else if (((found == 6 && events._released) || _key == Common::KEYCODE_PLUS || _key == Common::KEYCODE_KP_PLUS) && (inv._holdings - inv._invIndex) > 6) { @@ -1172,7 +1172,7 @@ void UserInterface::doInvControl() { screen.print(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1 + 1), COMMAND_HIGHLIGHTED, "_"); inv.freeGraphics(); inv.loadGraphics(); - inv.putInv(1); + inv.putInv(SLAM_DISPLAY); inv.invCommands(true); } else if (((found == 7 && events._released) || _key == '.') && (inv._holdings - inv._invIndex) > 6) { inv._invIndex += 6; @@ -1182,7 +1182,7 @@ void UserInterface::doInvControl() { screen.print(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1 + 1), COMMAND_HIGHLIGHTED, "_"); inv.freeGraphics(); inv.loadGraphics(); - inv.putInv(1); + inv.putInv(SLAM_DISPLAY); inv.invCommands(true); } else { // If something is being given, make sure it's to a person @@ -1226,7 +1226,7 @@ void UserInterface::doInvControl() { int temp = _selector; // Save the selector _selector = -1; - inv.putInv(1); + inv.putInv(SLAM_DISPLAY); _selector = temp; // Restore it temp = inv._invMode; inv._invMode = INVMODE_USE55; @@ -1300,7 +1300,7 @@ void UserInterface::doLookControl() { tempSurface.blitFrom(screen._backBuffer2, Common::Point(0, 0), Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); - inv.drawInventory(128); + inv.drawInventory(INVENTORY_DONT_DISPLAY); banishWindow(true); // Restore the ui @@ -1405,19 +1405,19 @@ void UserInterface::doMainControl() { pushButton(6); _selector = _oldSelector = -1; _menuMode = INV_MODE; - inv.drawInventory(1); + inv.drawInventory(PLAIN_INVENTORY); break; case 'U': pushButton(7); _selector = _oldSelector = -1; _menuMode = USE_MODE; - inv.drawInventory(2); + inv.drawInventory(USE_INVENTORY_MODE); break; case 'G': pushButton(8); _selector = _oldSelector = -1; _menuMode = GIVE_MODE; - inv.drawInventory(3); + inv.drawInventory(GIVE_INVENTORY_MODE); break; case 'J': pushButton(9); @@ -1904,7 +1904,7 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { // Reload the inventory graphics and draw the inventory inv.loadInv(); - inv.putInv(2); + inv.putInv(SLAM_SECONDARY_BUFFER); inv.freeInv(); banishWindow(1); @@ -2182,7 +2182,7 @@ void UserInterface::checkUseAction(const UseType *use, const Common::String &inv // Scan for target item int targetNum = -1; if (giveMode) { - for (int idx = 0; idx < 4 && targetNum == -1; ++idx) { + for (int idx = 0; idx < USE_COUNT && targetNum == -1; ++idx) { if ((use[idx]._target.equalsIgnoreCase("*GIVE*") || use[idx]._target.equalsIgnoreCase("*GIVEP*")) && use[idx]._names[0].equalsIgnoreCase(invName)) { // Found a match @@ -2192,7 +2192,7 @@ void UserInterface::checkUseAction(const UseType *use, const Common::String &inv } } } else { - for (int idx = 0; idx < 4 && targetNum == -1; ++idx) { + for (int idx = 0; idx < USE_COUNT && targetNum == -1; ++idx) { if (use[idx]._target.equalsIgnoreCase(invName)) targetNum = idx; } @@ -2216,7 +2216,7 @@ void UserInterface::checkUseAction(const UseType *use, const Common::String &inv if (!talk._talkToAbort) { Object &obj = scene._bgShapes[objNum]; - for (int idx = 0; idx < 4 && !talk._talkToAbort; ++idx) { + for (int idx = 0; idx < NAMES_COUNT && !talk._talkToAbort; ++idx) { if (obj.checkNameForCodes(action._names[idx], messages)) { if (!talk._talkToAbort) printed = true; @@ -2308,7 +2308,7 @@ void UserInterface::checkAction(ActionType &action, const char *const messages[] events.setCursor(WAIT); bool printed = false; - for (int nameIdx = 0; nameIdx < 4; ++nameIdx) { + for (int nameIdx = 0; nameIdx < NAMES_COUNT; ++nameIdx) { if (action._names[nameIdx].hasPrefix("*") && action._names[nameIdx].size() >= 2 && toupper(action._names[nameIdx][1]) == 'W') { if (obj.checkNameForCodes(Common::String(action._names[nameIdx].c_str() + 2), messages)) { @@ -2319,7 +2319,7 @@ void UserInterface::checkAction(ActionType &action, const char *const messages[] } bool doCAnim = true; - for (int nameIdx = 0; nameIdx < 4; ++nameIdx) { + for (int nameIdx = 0; nameIdx < NAMES_COUNT; ++nameIdx) { if (action._names[nameIdx].hasPrefix("*") && action._names[nameIdx].size() >= 2) { char ch = toupper(action._names[nameIdx][1]); @@ -2349,7 +2349,7 @@ void UserInterface::checkAction(ActionType &action, const char *const messages[] people.walkToCoords(pt, dir); } - for (int nameIdx = 0; nameIdx < 4; ++nameIdx) { + for (int nameIdx = 0; nameIdx < NAMES_COUNT; ++nameIdx) { if (action._names[nameIdx].hasPrefix("*") && action._names[nameIdx].size() >= 2 && toupper(action._names[nameIdx][1]) == 'F') { if (obj.checkNameForCodes(action._names[nameIdx].c_str() + 2, messages)) { @@ -2363,7 +2363,7 @@ void UserInterface::checkAction(ActionType &action, const char *const messages[] scene.startCAnim(cAnimNum, action._cAnimSpeed); if (!talk._talkToAbort) { - for (int nameIdx = 0; nameIdx < 4 && !talk._talkToAbort; ++nameIdx) { + for (int nameIdx = 0; nameIdx < NAMES_COUNT && !talk._talkToAbort; ++nameIdx) { if (obj.checkNameForCodes(action._names[nameIdx], messages)) { if (!talk._talkToAbort) printed = true; -- cgit v1.2.3 From b760c7d360d206d39391875e26271098c63acdd3 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 May 2015 19:37:54 -0400 Subject: SHERLOCK: More replacing numbers with constants --- engines/sherlock/journal.cpp | 28 +++++++++++++++------------- engines/sherlock/journal.h | 3 +++ engines/sherlock/scene.cpp | 2 +- engines/sherlock/talk.cpp | 40 +++++++++++++++++++++------------------- 4 files changed, 40 insertions(+), 33 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index f288b43650..71d104e3f7 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -29,7 +29,7 @@ namespace Sherlock { #define LINES_PER_PAGE 11 // Positioning of buttons in the journal view -const int JOURNAL_POINTS[9][3] = { +static const int JOURNAL_POINTS[9][3] = { { 6, 68, 37 }, { 69, 131, 100 }, { 132, 192, 162 }, @@ -41,7 +41,7 @@ const int JOURNAL_POINTS[9][3] = { { 237, 313, 275 } }; -const int SEARCH_POINTS[3][3] = { +static const int SEARCH_POINTS[3][3] = { { 51, 123, 86 }, { 124, 196, 159 }, { 197, 269, 232 } @@ -146,6 +146,8 @@ void Journal::loadJournalFile(bool alreadyLoaded) { Common::String dirFilename = _directory[journalEntry._converseNum]; bool replyOnly = journalEntry._replyOnly; + + // Get the location number from within the filename Common::String locStr(dirFilename.c_str() + 4, dirFilename.c_str() + 6); int newLocation = atoi(locStr.c_str()); @@ -195,11 +197,11 @@ void Journal::loadJournalFile(bool alreadyLoaded) { // See if title can fit into a single line, or requires splitting on 2 lines int width = screen.stringWidth(journalString.c_str() + 1); - if (width > 230) { + if (width > JOURNAL_MAX_WIDTH) { // Scan backwards from end of title to find a space between a word // where the width is less than the maximum allowed for the line const char *lineP = journalString.c_str() + journalString.size() - 1; - while (width > 230 || *lineP != ' ') + while (width > JOURNAL_MAX_WIDTH || *lineP != ' ') width -= screen.charWidth(*lineP--); // Split the header into two lines, and add a '@' prefix @@ -249,7 +251,7 @@ void Journal::loadJournalFile(bool alreadyLoaded) { byte c = *replyP++; // Is it a control character? - if (c < 128) { + if (c < SWITCH_SPEAKER) { // Nope. Set flag for allowing control codes to insert spaces ctrlSpace = true; assert(c >= ' '); @@ -296,7 +298,7 @@ void Journal::loadJournalFile(bool alreadyLoaded) { byte v; do { v = *strP++; - } while (v && (v < 128) && (v != '.') && (v != '!') && (v != '?')); + } while (v && (v < SWITCH_SPEAKER) && (v != '.') && (v != '!') && (v != '?')); if (v == '?') journalString += " asked, \""; @@ -312,11 +314,11 @@ void Journal::loadJournalFile(bool alreadyLoaded) { journalString += c; do { journalString += *replyP++; - } while (*replyP && *replyP < 128 && *replyP != '{' && *replyP != '}'); + } while (*replyP && *replyP < SWITCH_SPEAKER && *replyP != '{' && *replyP != '}'); commentJustPrinted = false; } - } else if (c == 128) { + } else if (c == SWITCH_SPEAKER) { if (!startOfReply) { if (!commentFlag && !commentJustPrinted) journalString += "\"\n"; @@ -343,7 +345,7 @@ void Journal::loadJournalFile(bool alreadyLoaded) { byte v; do { v = *strP++; - } while (v && v < 128 && v != '.' && v != '!' && v != '?'); + } while (v && v < SWITCH_SPEAKER && v != '.' && v != '!' && v != '?'); if (v == '?') journalString += " asked, \""; @@ -403,7 +405,7 @@ void Journal::loadJournalFile(bool alreadyLoaded) { // Put a space in the output for a control character, unless it's // immediately coming after another control character - if (ctrlSpace && c != 130 && c != 161 && !commentJustPrinted) { + if (ctrlSpace && c != ASSIGN_PORTRAIT_LOCATION && c != CARRIAGE_RETURN && !commentJustPrinted) { journalString += " "; ctrlSpace = false; } @@ -429,11 +431,11 @@ void Journal::loadJournalFile(bool alreadyLoaded) { // Build up chacters until a full line is found int width = 0; const char *endP = startP; - while (width < 230 && *endP && *endP != '\n' && (endP - startP) < 79) + while (width < JOURNAL_MAX_WIDTH && *endP && *endP != '\n' && (endP - startP) < (JOURNAL_MAX_CHARS - 1)) width += screen.charWidth(*endP++); // If word wrapping, move back to end of prior word - if (width >= 230 || (endP - startP) >= 79) { + if (width >= JOURNAL_MAX_WIDTH || (endP - startP) >= (JOURNAL_MAX_CHARS - 1)) { while (*--endP != ' ') ; } @@ -518,7 +520,7 @@ void Journal::drawInterface() { drawJournalFrame(); - if (_journal.size() == 0) { + if (_journal.empty()) { _up = _down = 0; } else { drawJournal(0, 0); diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h index be5c4d77c3..97696ef74f 100644 --- a/engines/sherlock/journal.h +++ b/engines/sherlock/journal.h @@ -31,6 +31,9 @@ namespace Sherlock { +#define JOURNAL_MAX_WIDTH 230 +#define JOURNAL_MAX_CHARS 80 + struct JournalEntry { int _converseNum; bool _replyOnly; diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index b092bbce65..78858bc284 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -1364,7 +1364,7 @@ void Scene::doBgAnim() { _animating = 0; screen.slamRect(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); } else { - if (people[AL]._type != INVALID && ((_goToScene == -1 || _canimShapes.size() == 0))) { + if (people[AL]._type != INVALID && ((_goToScene == -1 || _canimShapes.empty()))) { if (people[AL]._type == REMOVE) { screen.slamRect(Common::Rect( people[AL]._oldPosition.x, people[AL]._oldPosition.y, diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index dc5b9c5ba7..78b52bc7a5 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -26,6 +26,8 @@ namespace Sherlock { +#define SPEAKER_REMOVE 0x80 + SequenceEntry::SequenceEntry() { _objNum = 0; _frameNumber = 0; @@ -221,7 +223,7 @@ void Talk::talkTo(const Common::String &filename) { break; case TALK_MODE: - if (_speaker < 128) + if (_speaker < SPEAKER_REMOVE) people.clearTalking(); if (_talkCounter) return; @@ -464,7 +466,7 @@ void Talk::talk(int objNum) { ui._windowBounds.top = CONTROLS_Y; ui._infoFlag = true; - _speaker = 128; + _speaker = SPEAKER_REMOVE; loadTalkFile(scene._bgShapes[objNum]._name); // Find the first statement with the correct flags @@ -769,11 +771,11 @@ int Talk::talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt bool numberFlag = false; // Get the statement to display as well as optional number prefix - if (idx < 128) { + if (idx < SPEAKER_REMOVE) { number = Common::String::format("%d.", stateNum + 1); numberFlag = true; } else { - idx -= 128; + idx -= SPEAKER_REMOVE; } msg = _statements[idx]._statement; @@ -1019,7 +1021,7 @@ void Talk::doScript(const Common::String &script) { // Check if the script begins with a Stealh Mode Active command if (str[0] == STEALTH_MODE_ACTIVE || _talkStealth) { _talkStealth = 2; - _speaker |= 128; + _speaker |= SPEAKER_REMOVE; } else { pushSequence(_speaker); ui.clearWindow(); @@ -1077,11 +1079,11 @@ void Talk::doScript(const Common::String &script) { // Start of comment, so skip over it while (*str++ != '}') ; - } else if (c >= 128) { + } else if (c >= SWITCH_SPEAKER) { // Handle control code switch (c) { case SWITCH_SPEAKER: - if (!(_speaker & 128)) + if (!(_speaker & SPEAKER_REMOVE)) people.clearTalking(); if (_talkToAbort) return; @@ -1099,7 +1101,7 @@ void Talk::doScript(const Common::String &script) { case RUN_CANIMATION: ++str; - scene.startCAnim((str[0] - 1) & 127, (str[0] & 128) ? -1 : 1); + scene.startCAnim((str[0] - 1) & 127, (str[0] & 0x80) ? -1 : 1); if (_talkToAbort) return; @@ -1135,13 +1137,13 @@ void Talk::doScript(const Common::String &script) { break; case REMOVE_PORTRAIT: - if (_speaker >= 0 && _speaker < 128) + if (_speaker >= 0 && _speaker < SPEAKER_REMOVE) people.clearTalking(); pullSequence(); if (_talkToAbort) return; - _speaker |= 128; + _speaker |= SPEAKER_REMOVE; break; case CLEAR_WINDOW: @@ -1167,7 +1169,7 @@ void Talk::doScript(const Common::String &script) { error("Could not find object %s to change", tempString.c_str()); // Should the script be overwritten? - if (str[0] > 128) { + if (str[0] > 0x80) { // Save the current sequence _savedSequences.push(SequenceEntry()); SequenceEntry &seqEntry = _savedSequences.top(); @@ -1216,14 +1218,14 @@ void Talk::doScript(const Common::String &script) { break; case BANISH_WINDOW: - if (!(_speaker & 128)) + if (!(_speaker & SPEAKER_REMOVE)) people.clearTalking(); pullSequence(); if (_talkToAbort) return; - _speaker |= 128; + _speaker |= SPEAKER_REMOVE; ui.banishWindow(); ui._menuMode = TALK_MODE; noTextYet = true; @@ -1367,7 +1369,7 @@ void Talk::doScript(const Common::String &script) { tempString += str[idx + 1]; // Set comparison state according to if we want to hide or unhide - bool state = (str[0] >= 128); + bool state = (str[0] >= SPEAKER_REMOVE); str += str[0] & 127; for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) { @@ -1501,10 +1503,10 @@ void Talk::doScript(const Common::String &script) { width += screen.charWidth(str[idx]); ++idx; ++charCount; - } while (width < 298 && str[idx] && str[idx] != '{' && str[idx] < 128); + } while (width < 298 && str[idx] && str[idx] != '{' && str[idx] < SWITCH_SPEAKER); if (str[idx] || width >= 298) { - if (str[idx] < 128 && str[idx] != '{') { + if (str[idx] < SWITCH_SPEAKER && str[idx] != '{') { --idx; --charCount; } @@ -1544,7 +1546,7 @@ void Talk::doScript(const Common::String &script) { str += idx; // If line wrap occurred, then move to after the separating space between the words - if (str[0] < 128 && str[0] != '{') + if (str[0] < SWITCH_SPEAKER && str[0] != '{') ++str; yp += 9; @@ -1574,7 +1576,7 @@ void Talk::doScript(const Common::String &script) { } // Open window if it wasn't already open, and text has already been printed - if ((openTalkWindow && wait) || (openTalkWindow && str[0] >= 128 && str[0] != CARRIAGE_RETURN)) { + if ((openTalkWindow && wait) || (openTalkWindow && str[0] >= SWITCH_SPEAKER && str[0] != CARRIAGE_RETURN)) { if (!ui._windowStyle) { screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); } else { @@ -1624,7 +1626,7 @@ void Talk::doScript(const Common::String &script) { } pullSequence(); - if (_speaker >= 0 && _speaker < 128) + if (_speaker >= 0 && _speaker < SPEAKER_REMOVE) people.clearTalking(); } } -- cgit v1.2.3 From 19d93325b1ccda2d02d708cbef20a49786f38d2b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 May 2015 19:53:49 -0400 Subject: SHERLOCK: Move the override filename fields into the Animation class --- engines/sherlock/animation.cpp | 10 +++++----- engines/sherlock/animation.h | 3 +++ engines/sherlock/scalpel/scalpel.cpp | 32 ++++++++++++++++---------------- engines/sherlock/sherlock.h | 2 -- engines/sherlock/sound.cpp | 6 ++++-- engines/sherlock/sound.h | 2 +- 6 files changed, 29 insertions(+), 26 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 3c283636ca..8b891125cc 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -49,8 +49,8 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade, // Load the animation Common::SeekableReadStream *stream; - if (!_vm->_titleOverride.empty()) - stream = _vm->_res->load(vdxName, _vm->_titleOverride); + if (!_gfxLibraryFilename.empty()) + stream = _vm->_res->load(vdxName, _gfxLibraryFilename); else if (_vm->_useEpilogue2) stream = _vm->_res->load(vdxName, "epilog2.lib"); else @@ -105,12 +105,12 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade, if (frameNumber++ == *soundFrames) { ++soundNumber; ++soundFrames; - Common::String fname = _vm->_soundOverride.empty() ? + Common::String fname = _soundLibraryFilename.empty() ? Common::String::format("%s%01d", filename.c_str(), soundNumber) : Common::String::format("%s%02d", filename.c_str(), soundNumber); if (sound._voices) - sound.playSound(fname, WAIT_RETURN_IMMEDIATELY); + sound.playSound(fname, WAIT_RETURN_IMMEDIATELY, 100, _soundLibraryFilename.c_str()); } events.wait(speed * 3); @@ -184,7 +184,7 @@ void Animation::setTitleFrames(const int *frames, int count, int maxFrames) { const int *Animation::checkForSoundFrames(const Common::String &filename) { const int *frames = &NO_FRAMES; - if (_vm->_soundOverride.empty()) { + if (_soundLibraryFilename.empty()) { for (uint idx = 0; idx < _prologueNames.size(); ++idx) { if (filename.equalsIgnoreCase(_prologueNames[idx])) { frames = &_prologueFrames[idx][0]; diff --git a/engines/sherlock/animation.h b/engines/sherlock/animation.h index cd22a5c30a..2c47686efd 100644 --- a/engines/sherlock/animation.h +++ b/engines/sherlock/animation.h @@ -44,6 +44,9 @@ private: Common::Array > _titleFrames; const int *checkForSoundFrames(const Common::String &filename); +public: + Common::String _soundLibraryFilename; + Common::String _gfxLibraryFilename; public: Animation(SherlockEngine *vm); diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 0d62336283..fa55ca6013 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -302,8 +302,8 @@ bool ScalpelEngine::showCityCutscene() { byte palette[PALETTE_SIZE]; _sound->playMusic("prolog1.mus"); - _titleOverride = "title.lib"; - _soundOverride = "title.snd"; + _animation->_gfxLibraryFilename = "title.lib"; + _animation->_soundLibraryFilename = "title.snd"; bool finished = _animation->play("26open1", 1, 255, true, 2); if (finished) { @@ -365,8 +365,8 @@ bool ScalpelEngine::showCityCutscene() { } } - _titleOverride = ""; - _soundOverride = ""; + _animation->_gfxLibraryFilename = ""; + _animation->_soundLibraryFilename = ""; return finished; } @@ -377,8 +377,8 @@ bool ScalpelEngine::showAlleyCutscene() { byte palette[PALETTE_SIZE]; _sound->playMusic("prolog2.mus"); - _titleOverride = "TITLE.LIB"; - _soundOverride = "TITLE.SND"; + _animation->_gfxLibraryFilename = "TITLE.LIB"; + _animation->_soundLibraryFilename = "TITLE.SND"; bool finished = _animation->play("27PRO1", 1, 3, true, 2); if (finished) @@ -405,8 +405,8 @@ bool ScalpelEngine::showAlleyCutscene() { finished = _events->delay(1000); } - _titleOverride = ""; - _soundOverride = ""; + _animation->_gfxLibraryFilename = ""; + _animation->_soundLibraryFilename = ""; return finished; } @@ -414,8 +414,8 @@ bool ScalpelEngine::showAlleyCutscene() { * Show the Baker Street outside cutscene */ bool ScalpelEngine::showStreetCutscene() { - _titleOverride = "TITLE.LIB"; - _soundOverride = "TITLE.SND"; + _animation->_gfxLibraryFilename = "TITLE.LIB"; + _animation->_soundLibraryFilename = "TITLE.SND"; _sound->playMusic("PROLOG3.MUS"); @@ -424,8 +424,8 @@ bool ScalpelEngine::showStreetCutscene() { if (finished) finished = _animation->play("14NOTE", 1, 0, false, 2); - _titleOverride = ""; - _soundOverride = ""; + _animation->_gfxLibraryFilename = ""; + _animation->_soundLibraryFilename = ""; return finished; } @@ -469,8 +469,8 @@ bool ScalpelEngine::scrollCredits() { */ bool ScalpelEngine::showOfficeCutscene() { _sound->playMusic("PROLOG4.MUS"); - _titleOverride = "TITLE2.LIB"; - _soundOverride = "TITLE.SND"; + _animation->_gfxLibraryFilename = "TITLE2.LIB"; + _animation->_soundLibraryFilename = "TITLE.SND"; bool finished = _animation->play("COFF1", 1, 3, true, 3); if (finished) @@ -505,8 +505,8 @@ bool ScalpelEngine::showOfficeCutscene() { if (finished) _screen->fadeToBlack(3); - _titleOverride = ""; - _soundOverride = ""; + _animation->_gfxLibraryFilename = ""; + _animation->_soundLibraryFilename = ""; return finished; } diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 571bd4dc61..830a255f5f 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -99,8 +99,6 @@ public: UserInterface *_ui; Common::RandomSource _randomSource; Common::Array _flags; - Common::String _soundOverride; - Common::String _titleOverride; bool _useEpilogue2; int _loadGameSlot; bool _canLoadSave; diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index bcc6c96e4f..9693ccbd94 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -110,14 +110,16 @@ byte Sound::decodeSample(byte sample, byte &reference, int16 &scale) { return reference; } -bool Sound::playSound(const Common::String &name, WaitType waitType, int priority) { +bool Sound::playSound(const Common::String &name, WaitType waitType, int priority, const char *libraryFilename) { + Resources &res = *_vm->_res; stopSound(); Common::String filename = name; if (!filename.contains('.')) filename += ".SND"; - Common::SeekableReadStream *stream = _vm->_res->load(filename); + Common::String libFilename(libraryFilename); + Common::SeekableReadStream *stream = libFilename.empty() ? res.load(filename) : res.load(filename, libFilename); if (!stream) error("Unable to find sound file '%s'", filename.c_str()); diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index 62d4aa24c4..bff50d7a07 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -63,7 +63,7 @@ public: void syncSoundSettings(); void loadSound(const Common::String &name, int priority); - bool playSound(const Common::String &name, WaitType waitType, int priority = 100); + bool playSound(const Common::String &name, WaitType waitType, int priority = 100, const char *libraryFilename = nullptr); void playLoadedSound(int bufNum, WaitType waitType); void freeLoadedSounds(); void stopSound(); -- cgit v1.2.3 From 8d426ca46435426c925007b08c933fdccdd75fa8 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 May 2015 20:43:26 -0400 Subject: SHERLOCK: Added more of the game options to the Engine tab --- engines/sherlock/detection.cpp | 45 +++++++++++++++++++++++++++++++++++++ engines/sherlock/detection_tables.h | 3 ++- engines/sherlock/inventory.cpp | 2 +- engines/sherlock/saveload.cpp | 2 +- engines/sherlock/settings.cpp | 8 +++---- engines/sherlock/sherlock.cpp | 9 ++------ engines/sherlock/talk.cpp | 6 ++--- engines/sherlock/user_interface.cpp | 8 +++---- engines/sherlock/user_interface.h | 2 +- 9 files changed, 63 insertions(+), 22 deletions(-) diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp index e69887b5c7..096eb9f46e 100644 --- a/engines/sherlock/detection.cpp +++ b/engines/sherlock/detection.cpp @@ -60,6 +60,10 @@ static const PlainGameDescriptor sherlockGames[] = { #define GAMEOPTION_ORIGINAL_SAVES GUIO_GAMEOPTIONS1 +#define GAMEOPTION_FADE_STYLE GUIO_GAMEOPTIONS2 +#define GAMEOPTION_HELP_STYLE GUIO_GAMEOPTIONS3 +#define GAMEOPTION_PORTRAITS_ON GUIO_GAMEOPTIONS4 +#define GAMEOPTION_WINDOW_STYLE GUIO_GAMEOPTIONS5 static const ADExtraGuiOptionsMap optionsList[] = { { @@ -72,9 +76,50 @@ static const ADExtraGuiOptionsMap optionsList[] = { } }, + { + GAMEOPTION_FADE_STYLE, + { + _s("Pixellated scene transitions"), + _s("When changing scenes, a randomized pixel transition is done"), + "fade_style", + true + } + }, + + { + GAMEOPTION_HELP_STYLE, + { + _s("Don't show hotspots when moving mouse"), + _s("Only show hotspot names after you actually click on a hotspot or action button"), + "help_style", + false + } + }, + + { + GAMEOPTION_PORTRAITS_ON, + { + _s("Show character portraits"), + _s("Show portraits for the characters when conversing"), + "portraits_on", + true + } + }, + + { + GAMEOPTION_WINDOW_STYLE, + { + _s("Slide dialogs into view"), + _s("Slide UI dialogs into view, rather than simply showing them immediately"), + "window_style", + true + } + }, + AD_EXTRA_GUI_OPTIONS_TERMINATOR }; + #include "sherlock/detection_tables.h" class SherlockMetaEngine : public AdvancedMetaEngine { diff --git a/engines/sherlock/detection_tables.h b/engines/sherlock/detection_tables.h index 3960836f82..a13231d3fc 100644 --- a/engines/sherlock/detection_tables.h +++ b/engines/sherlock/detection_tables.h @@ -33,7 +33,8 @@ static const SherlockGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, - GUIO2(GUIO_NOSPEECH, GAMEOPTION_ORIGINAL_SAVES) + GUIO6(GUIO_NOSPEECH, GAMEOPTION_ORIGINAL_SAVES, GAMEOPTION_FADE_STYLE, GAMEOPTION_HELP_STYLE, + GAMEOPTION_PORTRAITS_ON, GAMEOPTION_WINDOW_STYLE) }, GType_SerratedScalpel, }, diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index 283164c534..d41e4b9b3e 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -255,7 +255,7 @@ void Inventory::drawInventory(InvNewMode mode) { putInv(SLAM_DONT_DISPLAY); if (tempMode != INVENTORY_DONT_DISPLAY) { - if (!ui._windowStyle) { + if (!ui._slideWindows) { screen.slamRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); } else { ui.summonWindow(false, CONTROLS_Y1); diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index 0ac25a2f1a..6fb1dcc448 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -98,7 +98,7 @@ void SaveManager::drawInterface() { INV_FOREGROUND, "%s", _savegames[idx].c_str()); } - if (!ui._windowStyle) { + if (!ui._slideWindows) { screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); } else { ui.summonWindow(); diff --git a/engines/sherlock/settings.cpp b/engines/sherlock/settings.cpp index ffa1f056de..b4110d593c 100644 --- a/engines/sherlock/settings.cpp +++ b/engines/sherlock/settings.cpp @@ -108,7 +108,7 @@ void Settings::drawInteface(bool flag) { screen.makeButton(Common::Rect(SETUP_POINTS[8][0], SETUP_POINTS[8][1], SETUP_POINTS[8][2], SETUP_POINTS[8][1] + 10), SETUP_POINTS[8][3] - screen.stringWidth(tempStr) / 2, tempStr); - tempStr = Common::String::format("Windows %s", ui._windowStyle ? "Slide" : "Appear"); + tempStr = Common::String::format("Windows %s", ui._slideWindows ? "Slide" : "Appear"); screen.makeButton(Common::Rect(SETUP_POINTS[9][0], SETUP_POINTS[9][1], SETUP_POINTS[9][2], SETUP_POINTS[9][1] + 10), SETUP_POINTS[9][3] - screen.stringWidth(tempStr) / 2, tempStr); @@ -123,7 +123,7 @@ void Settings::drawInteface(bool flag) { // Show the window immediately, or slide it on-screen if (!flag) { - if (!ui._windowStyle) { + if (!ui._slideWindows) { screen.slamRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); } else { ui.summonWindow(true, CONTROLS_Y1); @@ -189,7 +189,7 @@ int Settings::drawButtons(const Common::Point &pt, int _key) { screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); break; case 9: - tempStr = Common::String::format("Windows %s", SETUP_STRS3[ui._windowStyle]); + tempStr = Common::String::format("Windows %s", SETUP_STRS3[ui._slideWindows]); screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); break; case 10: @@ -322,7 +322,7 @@ void Settings::show(SherlockEngine *vm) { if ((found == 9 && events._released) || ui._key == 'W') { // Window style - ui._windowStyle ^= 1; + ui._slideWindows = !ui._slideWindows; updateConfig = true; settings.drawInteface(true); } diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index eb80fb6e3b..bd8dcb69ee 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -230,16 +230,11 @@ void SherlockEngine::loadConfig() { syncSoundSettings(); ConfMan.registerDefault("font", 1); - ConfMan.registerDefault("fade_style", true); - ConfMan.registerDefault("help_style", false); - ConfMan.registerDefault("window_style", 1); - ConfMan.registerDefault("portraits_on", true); - ConfMan.registerDefault("originalsaveload", false); _screen->setFont(ConfMan.getInt("font")); _screen->_fadeStyle = ConfMan.getBool("fade_style"); _ui->_helpStyle = ConfMan.getBool("help_style"); - _ui->_windowStyle = ConfMan.getInt("window_style"); + _ui->_slideWindows = ConfMan.getBool("window_style"); _people->_portraitsOn = ConfMan.getBool("portraits_on"); } @@ -254,7 +249,7 @@ void SherlockEngine::saveConfig() { ConfMan.setInt("font", _screen->fontNumber()); ConfMan.setBool("fade_style", _screen->_fadeStyle); ConfMan.setBool("help_style", _ui->_helpStyle); - ConfMan.setInt("window_style", _ui->_windowStyle); + ConfMan.setBool("window_style", _ui->_slideWindows); ConfMan.setBool("portraits_on", _people->_portraitsOn); ConfMan.flushToDisk(); diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 78b52bc7a5..ec7e63e835 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -387,7 +387,7 @@ void Talk::talkTo(const Common::String &filename) { } else { screen.buttonPrint(Common::Point(119, CONTROLS_Y), color, false, "Exit"); - if (!ui._windowStyle) { + if (!ui._slideWindows) { screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); } else { @@ -534,7 +534,7 @@ void Talk::talk(int objNum) { displayTalk(false); ui._selector = ui._oldSelector = -1; - if (!ui._windowStyle) { + if (!ui._slideWindows) { screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); } else { @@ -1577,7 +1577,7 @@ void Talk::doScript(const Common::String &script) { // Open window if it wasn't already open, and text has already been printed if ((openTalkWindow && wait) || (openTalkWindow && str[0] >= SWITCH_SPEAKER && str[0] != CARRIAGE_RETURN)) { - if (!ui._windowStyle) { + if (!ui._slideWindows) { screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); } else { ui.summonWindow(); diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index ffcbddb920..1607c727eb 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -109,7 +109,7 @@ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { _selector = _oldSelector = -1; _windowBounds = Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH - 1, SHERLOCK_SCREEN_HEIGHT - 1); - _windowStyle = 1; // Sliding windows + _slideWindows = true; _find = 0; _oldUse = 0; _endKeyActive = true; @@ -1999,7 +1999,7 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { } if (firstTime) { - if (!_windowStyle) { + if (!_slideWindows) { screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); } else { @@ -2094,10 +2094,10 @@ void UserInterface::banishWindow(bool slideUp) { Screen &screen = *_vm->_screen; if (_windowOpen) { - if (slideUp || !_windowStyle) { + if (slideUp || !_slideWindows) { // Slide window down // Only slide the window if the window style allows it - if (_windowStyle) { + if (_slideWindows) { for (int idx = 2; idx < (SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y); idx += 2) { // Shift the window down by 2 lines byte *pSrc = (byte *)screen._backBuffer1.getBasePtr(0, CONTROLS_Y + idx - 2); diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index 2ff60715e3..fdaa323e5e 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -122,7 +122,7 @@ public: bool _endKeyActive; int _invLookFlag; int _temp1; - int _windowStyle; + bool _slideWindows; bool _helpStyle; public: UserInterface(SherlockEngine *vm); -- cgit v1.2.3 From a09937121c3844071ab992115f32b47d57a5d337 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 May 2015 20:57:58 -0400 Subject: SHERLOCK: Syntactic fixes --- engines/sherlock/scene.cpp | 12 +++++++----- engines/sherlock/screen.cpp | 10 ++-------- engines/sherlock/screen.h | 4 ++-- engines/sherlock/settings.cpp | 16 ++++++++-------- engines/sherlock/sherlock.cpp | 2 ++ engines/sherlock/sound.cpp | 38 ++++++++++++++++++++------------------ engines/sherlock/talk.cpp | 2 +- 7 files changed, 42 insertions(+), 42 deletions(-) diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 78858bc284..e71bc7eef7 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -26,6 +26,13 @@ namespace Sherlock { +static const int FS_TRANS[8] = { + STOP_UP, STOP_UPRIGHT, STOP_RIGHT, STOP_DOWNRIGHT, STOP_DOWN, + STOP_DOWNLEFT, STOP_LEFT, STOP_UPLEFT +}; + +/*----------------------------------------------------------------*/ + /** * Load the data for the object */ @@ -637,11 +644,6 @@ void Scene::transitionToScene() { Common::Point &hSavedPos = people._hSavedPos; int &hSavedFacing = people._hSavedFacing; - const int FS_TRANS[8] = { - STOP_UP, STOP_UPRIGHT, STOP_RIGHT, STOP_DOWNRIGHT, STOP_DOWN, - STOP_DOWNLEFT, STOP_LEFT, STOP_UPLEFT - }; - if (hSavedPos.x < 1) { // No exit information from last scene-check entrance info if (_entrance._startPosition.x < 1) { diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index d9ec1d745d..4c70bf21c5 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -328,13 +328,10 @@ void Screen::flushImage(ImageFrame *frame, const Common::Point &pt, */ void Screen::print(const Common::Point &pt, byte color, const char *formatStr, ...) { // Create the string to display - char buffer[100]; va_list args; - va_start(args, formatStr); - vsprintf(buffer, formatStr, args); + Common::String str = Common::String::vformat(formatStr, args); va_end(args); - Common::String str(buffer); // Figure out area to draw text in Common::Point pos = pt; @@ -362,13 +359,10 @@ void Screen::print(const Common::Point &pt, byte color, const char *formatStr, . */ void Screen::gPrint(const Common::Point &pt, byte color, const char *formatStr, ...) { // Create the string to display - char buffer[100]; va_list args; - va_start(args, formatStr); - vsprintf(buffer, formatStr, args); + Common::String str = Common::String::vformat(formatStr, args); va_end(args); - Common::String str(buffer); // Print the text writeString(str, pt, color); diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 2103588fe0..452a18631f 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -101,8 +101,8 @@ public: void verticalTransition(); - void print(const Common::Point &pt, byte color, const char *formatStr, ...); - void gPrint(const Common::Point &pt, byte color, const char *formatStr, ...); + void print(const Common::Point &pt, byte color, const char *formatStr, ...) GCC_PRINTF(4, 5); + void gPrint(const Common::Point &pt, byte color, const char *formatStr, ...) GCC_PRINTF(4, 5); void restoreBackground(const Common::Rect &r); diff --git a/engines/sherlock/settings.cpp b/engines/sherlock/settings.cpp index b4110d593c..036177adbe 100644 --- a/engines/sherlock/settings.cpp +++ b/engines/sherlock/settings.cpp @@ -25,7 +25,7 @@ namespace Sherlock { -const int SETUP_POINTS[12][4] = { +static const int SETUP_POINTS[12][4] = { { 4, 154, 101, 53 }, // Exit { 4, 165, 101, 53 }, // Music Toggle { 219, 165, 316, 268 }, // Voice Toggle @@ -40,13 +40,13 @@ const int SETUP_POINTS[12][4] = { { 219, 187, 316, 268 } // _key Pad Accel. Toggle }; -const char *const SETUP_STRS0[2] = { "off", "on" }; -const char *const SETUP_STRS1[2] = { "Directly", "by Pixel" }; -const char *const SETUP_STRS2[2] = { "Left", "Right" }; -const char *const SETUP_STRS3[2] = { "Appear", "Slide" }; -const char *const SETUP_STRS4[2] = { "Slow", "Fast" }; -const char *const SETUP_STRS5[2] = { "Left", "Right" }; -const char *const SETUP_NAMES[12] = { +static const char *const SETUP_STRS0[2] = { "off", "on" }; +static const char *const SETUP_STRS1[2] = { "Directly", "by Pixel" }; +static const char *const SETUP_STRS2[2] = { "Left", "Right" }; +static const char *const SETUP_STRS3[2] = { "Appear", "Slide" }; +static const char *const SETUP_STRS4[2] = { "Slow", "Fast" }; +static const char *const SETUP_STRS5[2] = { "Left", "Right" }; +static const char *const SETUP_NAMES[12] = { "Exit", "M", "V", "S", "B", "New Font Style", "J", "Calibrate Joystick", "F", "W", "P", "K" }; diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index bd8dcb69ee..fd5c9a84d5 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -203,6 +203,8 @@ void SherlockEngine::handleInput() { /** * Read the state of a global flag + * @remarks If a negative value is specified, it will return the inverse value + * of the positive flag number */ bool SherlockEngine::readFlags(int flagNum) { bool value = _flags[ABS(flagNum)]; diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index 9693ccbd94..205178c0ec 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -30,6 +30,26 @@ namespace Sherlock { +static const int8 creativeADPCM_ScaleMap[64] = { + 0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7, + 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15, + 2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30, + 4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60 +}; + +static const uint8 creativeADPCM_AdjustMap[64] = { + 0, 0, 0, 0, 0, 16, 16, 16, + 0, 0, 0, 0, 0, 16, 16, 16, + 240, 0, 0, 0, 0, 16, 16, 16, + 240, 0, 0, 0, 0, 16, 16, 16, + 240, 0, 0, 0, 0, 16, 16, 16, + 240, 0, 0, 0, 0, 16, 16, 16, + 240, 0, 0, 0, 0, 0, 0, 0, + 240, 0, 0, 0, 0, 0, 0, 0 +}; + +/*----------------------------------------------------------------*/ + Sound::Sound(SherlockEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) { _digitized = false; _music = false; @@ -70,24 +90,6 @@ void Sound::loadSound(const Common::String &name, int priority) { warning("loadSound"); } -static int8 creativeADPCM_ScaleMap[64] = { - 0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7, - 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15, - 2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30, - 4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60 -}; - -static uint8 creativeADPCM_AdjustMap[64] = { - 0, 0, 0, 0, 0, 16, 16, 16, - 0, 0, 0, 0, 0, 16, 16, 16, - 240, 0, 0, 0, 0, 16, 16, 16, - 240, 0, 0, 0, 0, 16, 16, 16, - 240, 0, 0, 0, 0, 16, 16, 16, - 240, 0, 0, 0, 0, 16, 16, 16, - 240, 0, 0, 0, 0, 0, 0, 0, - 240, 0, 0, 0, 0, 0, 0, 0 -}; - byte Sound::decodeSample(byte sample, byte &reference, int16 &scale) { int16 samp = sample + scale; int16 ref = 0; diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index ec7e63e835..79ed052c1e 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1665,7 +1665,7 @@ int Talk::waitForMore(int delay) { if (events.kbHit()) { Common::KeyState keyState = events.getKey(); - if (keyState.keycode >= 32 && keyState.keycode < 128) + if (keyState.keycode >= ' ' && keyState.keycode < '~') key2 = keyState.keycode; } -- cgit v1.2.3 From 7c3ac25ac153a2934ee94c8aa83b72843bd56351 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 May 2015 23:44:59 -0400 Subject: SHERLOCK: Further syntactic fixes --- engines/sherlock/journal.cpp | 58 +++++++++++++++++++----------------------- engines/sherlock/journal.h | 2 +- engines/sherlock/objects.cpp | 6 ++--- engines/sherlock/objects.h | 4 +-- engines/sherlock/resources.cpp | 9 +++---- engines/sherlock/screen.cpp | 4 +-- engines/sherlock/talk.cpp | 2 +- 7 files changed, 39 insertions(+), 46 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 71d104e3f7..be2a013069 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -27,6 +27,10 @@ namespace Sherlock { #define JOURNAL_BUTTONS_Y 178 #define LINES_PER_PAGE 11 +#define JOURNAL_SEARCH_LEFT 15 +#define JOURNAL_SEARCH_TOP 186 +#define JOURNAL_SEARCH_RIGHT 296 +#define JOURNAL_SEACRH_MAX_CHARS 50 // Positioning of buttons in the journal view static const int JOURNAL_POINTS[9][3] = { @@ -910,11 +914,11 @@ bool Journal::handleEvents(int key) { screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11), COMMAND_NULL, true, "Print Text"); } - if (found == BTN_EXIT && events._released) + if (found == BTN_EXIT && events._released) { // Exit button pressed doneFlag = true; - if (((found == BTN_BACK10 && events._released) || key == 'B') && (_page > 1)) { + } else if (((found == BTN_BACK10 && events._released) || key == 'B') && (_page > 1)) { // Scrolll up 10 pages if (_page < 11) drawJournal(1, (_page - 1) * LINES_PER_PAGE); @@ -923,23 +927,20 @@ bool Journal::handleEvents(int key) { doArrows(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); - } - if (((found == BTN_UP && events._released) || key == 'U') && _up) { + } else if (((found == BTN_UP && events._released) || key == 'U') && _up) { // Scroll up drawJournal(1, LINES_PER_PAGE); doArrows(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); - } - - if (((found == BTN_DOWN && events._released) || key == 'D') && _down) { + + } else if (((found == BTN_DOWN && events._released) || key == 'D') && _down) { // Scroll down drawJournal(2, LINES_PER_PAGE); doArrows(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); - } - if (((found == BTN_AHEAD110 && events._released) || key == 'A') && _down) { + } else if (((found == BTN_AHEAD110 && events._released) || key == 'A') && _down) { // Scroll down 10 pages if ((_page + 10) > _maxPage) drawJournal(2, (_maxPage - _page) * LINES_PER_PAGE); @@ -948,15 +949,14 @@ bool Journal::handleEvents(int key) { doArrows(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); - } - - if (((found == BTN_SEARCH && events._released) || key == 'S') && !_journal.empty()) { + + } else if (((found == BTN_SEARCH && events._released) || key == 'S') && !_journal.empty()) { screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), COMMAND_FOREGROUND, true, "Search"); bool notFound = false; do { int dir; - if ((dir = getFindName(notFound)) != 0) { + if ((dir = getSearchString(notFound)) != 0) { int savedIndex = _index; int savedSub = _sub; int savedPage = _page; @@ -980,9 +980,8 @@ bool Journal::handleEvents(int key) { } } while (!doneFlag); doneFlag = false; - } - - if (((found == BTN_FIRST_PAGE && events._released) || key == 'F') && _up) { + + } else if (((found == BTN_FIRST_PAGE && events._released) || key == 'F') && _up) { // First page _index = _sub = 0; _up = _down = false; @@ -992,9 +991,8 @@ bool Journal::handleEvents(int key) { drawJournal(0, 0); doArrows(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); - } - - if (((found == BTN_LAST_PAGE && events._released) || key == 'L') && _down) { + + } else if (((found == BTN_LAST_PAGE && events._released) || key == 'L') && _down) { // Last page if ((_page + 10) > _maxPage) drawJournal(2, (_maxPage - _page) * LINES_PER_PAGE); @@ -1011,9 +1009,9 @@ bool Journal::handleEvents(int key) { } /** - * Show the search submenu + * Show the search submenu and allow the player to enter a search string */ -int Journal::getFindName(bool printError) { +int Journal::getSearchString(bool printError) { enum Button { BTN_NONE, BTN_EXIT, BTN_BACKWARD, BTN_FORWARD }; Events &events = *_vm->_events; @@ -1078,8 +1076,8 @@ int Journal::getFindName(bool printError) { screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } - xp = 15 + screen.stringWidth(name); - yp = 186; + xp = JOURNAL_SEARCH_LEFT + screen.stringWidth(name); + yp = JOURNAL_SEARCH_TOP; do { events._released = false; @@ -1136,18 +1134,14 @@ int Journal::getFindName(bool printError) { name.deleteLastChar(); } - if (keyState.keycode == Common::KEYCODE_RETURN) + if (keyState.keycode == Common::KEYCODE_RETURN) { done = 1; - - if (keyState.keycode == Common::KEYCODE_ESCAPE) { + } else if (keyState.keycode == Common::KEYCODE_ESCAPE) { screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), BUTTON_MIDDLE); done = -1; - } - - if (keyState.keycode >= Common::KEYCODE_SPACE && keyState.keycode <= Common::KEYCODE_z - && keyState.keycode != Common::KEYCODE_AT && name.size() < 50 - && (xp + screen.charWidth(keyState.keycode)) < 296) { - char ch = toupper(keyState.keycode); + } else if (keyState.ascii >= ' ' && keyState.keycode <= 'z' && keyState.keycode != Common::KEYCODE_AT && + name.size() < JOURNAL_SEACRH_MAX_CHARS && (xp + screen.charWidth(keyState.keycode)) < JOURNAL_SEARCH_RIGHT) { + char ch = toupper(keyState.ascii); screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), BUTTON_MIDDLE); screen.print(Common::Point(xp, yp), TALK_FOREGROUND, "%c", ch); xp += screen.charWidth(ch); diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h index 97696ef74f..026579bac2 100644 --- a/engines/sherlock/journal.h +++ b/engines/sherlock/journal.h @@ -68,7 +68,7 @@ private: bool drawJournal(int direction, int howFar); - int getFindName(bool printError); + int getSearchString(bool printError); void drawJournalFrame(); public: diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 310afbf94b..eb4676dd5f 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -566,7 +566,7 @@ void Object::toggleHidden() { void Object::checkObject() { Scene &scene = *_vm->_scene; Sound &sound = *_vm->_sound; - int checkFrame = _allow ? MAX_FRAME : 32000; + int checkFrame = _allow ? MAX_FRAME : FRAMES_END; bool codeFound; if (_seqTo) { @@ -693,7 +693,7 @@ void Object::checkObject() { */ bool Object::checkEndOfSequence() { Screen &screen = *_vm->_screen; - int checkFrame = _allow ? MAX_FRAME : 32000; + int checkFrame = _allow ? MAX_FRAME : FRAMES_END; bool result = false; if (_type == REMOVE || _type == INVALID) @@ -749,7 +749,7 @@ bool Object::checkEndOfSequence() { */ void Object::setObjSequence(int seq, bool wait) { Scene &scene = *_vm->_scene; - int checkFrame = _allow ? MAX_FRAME : 32000; + int checkFrame = _allow ? MAX_FRAME : FRAMES_END; if (seq >= 128) { // Loop the sequence until the count exceeded diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 0b3a26f1f9..e3e07d89b7 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -102,8 +102,8 @@ class Sprite { private: static SherlockEngine *_vm; public: - Common::String _name; // Name - Common::String _description; // Description + Common::String _name; + Common::String _description; Common::StringArray _examine; // Examine in-depth description Common::String _pickUp; // Message for if you can't pick up object diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index fa68074c60..5a98d57011 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -156,12 +156,11 @@ Common::SeekableReadStream *Resources::load(const Common::String &filename) { // Secondly, iterate through any loaded library file looking for a resource // that has the same name - LibraryIndexes::iterator i; - for (i = _indexes.begin(); i != _indexes.end(); ++i) { - if ((*i)._value.contains(filename)) { + for (LibraryIndexes::iterator i = _indexes.begin(); i != _indexes.end(); ++i) { + if (i->_value.contains(filename)) { // Get a stream reference to the given library file - Common::SeekableReadStream *stream = load((*i)._key); - LibraryEntry &entry = (*i)._value[filename]; + Common::SeekableReadStream *stream = load(i->_key); + LibraryEntry &entry = i->_value[filename]; _resourceIndex = entry._index; stream->seek(entry._offset); diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 4c70bf21c5..f43bf17288 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -387,7 +387,7 @@ int Screen::stringWidth(const Common::String &str) { int Screen::charWidth(char c) { if (c == ' ') return 5; - else if (c > ' ' && c <= '~') + else if (Common::isPrint(c)) return (*_font)[c - 33]._frame.w + 1; else return 0; @@ -403,7 +403,7 @@ void Screen::writeString(const Common::String &str, const Common::Point &pt, byt if (*c == ' ') charPos.x += 5; else { - assert(*c > ' ' && *c <= '~'); + assert(Common::isPrint(*c)); ImageFrame &frame = (*_font)[*c - 33]; _backBuffer->transBlitFrom(frame, charPos, false, color); charPos.x += frame._frame.w + 1; diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 79ed052c1e..fd0b7cb378 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1665,7 +1665,7 @@ int Talk::waitForMore(int delay) { if (events.kbHit()) { Common::KeyState keyState = events.getKey(); - if (keyState.keycode >= ' ' && keyState.keycode < '~') + if (Common::isPrint(keyState.ascii)) key2 = keyState.keycode; } -- cgit v1.2.3 From 338fd4697642dac417be53d21cfc537a30f74f3c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 May 2015 23:57:08 -0400 Subject: SHERLOCK: Cleanup of Journal::handleEvents --- engines/sherlock/journal.cpp | 106 +++++++++++++++++++++++++------------------ engines/sherlock/journal.h | 9 ++++ 2 files changed, 70 insertions(+), 45 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index be2a013069..34a58b5871 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -808,6 +808,49 @@ bool Journal::drawJournal(int direction, int howFar) { return direction >= 3 && searchSuccessful; } +/** + * Returns the button, if any, that is under the specified position + */ +JournalButton Journal::getHighlightedButton(const Common::Point &pt) { + if (pt.x > JOURNAL_POINTS[0][0] && pt.x < JOURNAL_POINTS[0][1] && pt.y >= JOURNAL_BUTTONS_Y && + pt.y < (JOURNAL_BUTTONS_Y + 10)) + return BTN_EXIT; + + if (pt.x > JOURNAL_POINTS[1][0] && pt.x < JOURNAL_POINTS[1][1] && pt.y >= JOURNAL_BUTTONS_Y && + pt.y < (JOURNAL_BUTTONS_Y + 10) && _page > 1) + return BTN_BACK10; + + if (pt.x > JOURNAL_POINTS[2][0] && pt.x < JOURNAL_POINTS[2][1] && pt.y >= JOURNAL_BUTTONS_Y && + pt.y < (JOURNAL_BUTTONS_Y + 10) && _up) + return BTN_UP; + + if (pt.x > JOURNAL_POINTS[3][0] && pt.x < JOURNAL_POINTS[3][1] && pt.y >= JOURNAL_BUTTONS_Y && + pt.y < (JOURNAL_BUTTONS_Y + 10) && _down) + return BTN_DOWN; + + if (pt.x > JOURNAL_POINTS[4][0] && pt.x < JOURNAL_POINTS[4][1] && pt.y >= JOURNAL_BUTTONS_Y && + pt.y < (JOURNAL_BUTTONS_Y + 10) && _down) + return BTN_AHEAD110; + + if (pt.x > JOURNAL_POINTS[5][0] && pt.x < JOURNAL_POINTS[5][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) && + pt.y < (JOURNAL_BUTTONS_Y + 20) && !_journal.empty()) + return BTN_SEARCH; + + if (pt.x > JOURNAL_POINTS[6][0] && pt.x < JOURNAL_POINTS[6][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) && + pt.y < (JOURNAL_BUTTONS_Y + 20) && _up) + return BTN_FIRST_PAGE; + + if (pt.x > JOURNAL_POINTS[7][0] && pt.x < JOURNAL_POINTS[7][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) && + pt.y < (JOURNAL_BUTTONS_Y + 20) && _down) + return BTN_LAST_PAGE; + + if (pt.x > JOURNAL_POINTS[8][0] && pt.x < JOURNAL_POINTS[8][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) && + pt.y < (JOURNAL_BUTTONS_Y + 20) && !_journal.empty()) + return BTN_PRINT_TEXT; + + return BTN_NONE; +} + /** * Handle events whilst the journal is being displayed */ @@ -815,65 +858,46 @@ bool Journal::handleEvents(int key) { Events &events = *_vm->_events; Screen &screen = *_vm->_screen; bool doneFlag = false; + Common::Point pt = events.mousePos(); + JournalButton btn = getHighlightedButton(pt); byte color; - enum Button { - BTN_NONE, BTN_EXIT, BTN_BACK10, BTN_UP, BTN_DOWN, BTN_AHEAD110, BTN_SEARCH, - BTN_FIRST_PAGE, BTN_LAST_PAGE, BTN_PRINT_TEXT - }; - Button found = BTN_NONE; if (events._pressed || events._released) { // Exit button - if (pt.x > JOURNAL_POINTS[0][0] && pt.x < JOURNAL_POINTS[0][1] && pt.y >= JOURNAL_BUTTONS_Y && - pt.y < (JOURNAL_BUTTONS_Y + 10)) { - found = BTN_EXIT; - color = COMMAND_HIGHLIGHTED; - } else { - color = COMMAND_FOREGROUND; - } + color = (btn == BTN_EXIT) ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND; screen.buttonPrint(Common::Point(JOURNAL_POINTS[0][2], JOURNAL_BUTTONS_Y), color, true, "Exit"); // Back 10 button - if (pt.x > JOURNAL_POINTS[1][0] && pt.x < JOURNAL_POINTS[1][1] && pt.y >= JOURNAL_BUTTONS_Y && - pt.y < (JOURNAL_BUTTONS_Y + 10) && _page > 1) { - found = BTN_BACK10; + if (btn == BTN_BACK10) { screen.buttonPrint(Common::Point(JOURNAL_POINTS[1][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, "Back 10"); } else if (_page > 1) { screen.buttonPrint(Common::Point(JOURNAL_POINTS[1][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, "Back 10"); } // Up button - if (pt.x > JOURNAL_POINTS[2][0] && pt.x < JOURNAL_POINTS[2][1] && pt.y >= JOURNAL_BUTTONS_Y && - pt.y < (JOURNAL_BUTTONS_Y + 10) && _up) { - found = BTN_UP; + if (btn == BTN_UP) { screen.buttonPrint(Common::Point(JOURNAL_POINTS[2][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, "Up"); } else if (_up) { screen.buttonPrint(Common::Point(JOURNAL_POINTS[2][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, "Up"); } // Down button - if (pt.x > JOURNAL_POINTS[3][0] && pt.x < JOURNAL_POINTS[3][1] && pt.y >= JOURNAL_BUTTONS_Y && - pt.y < (JOURNAL_BUTTONS_Y + 10) && _down) { - found = BTN_DOWN; + if (btn == BTN_DOWN) { screen.buttonPrint(Common::Point(JOURNAL_POINTS[3][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, "Down"); } else if (_down) { screen.buttonPrint(Common::Point(JOURNAL_POINTS[3][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, "Down"); } // Ahead 10 button - if (pt.x > JOURNAL_POINTS[4][0] && pt.x < JOURNAL_POINTS[4][1] && pt.y >= JOURNAL_BUTTONS_Y && - pt.y < (JOURNAL_BUTTONS_Y + 10) && _down) { - found = BTN_AHEAD110; + if (btn == BTN_AHEAD110) { screen.buttonPrint(Common::Point(JOURNAL_POINTS[4][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, "Ahead 10"); } else if (_down) { screen.buttonPrint(Common::Point(JOURNAL_POINTS[4][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, "Ahead 10"); } // Search button - if (pt.x > JOURNAL_POINTS[5][0] && pt.x < JOURNAL_POINTS[5][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) && - pt.y < (JOURNAL_BUTTONS_Y + 20) && !_journal.empty()) { - found = BTN_SEARCH; + if (btn == BTN_SEARCH) { color = COMMAND_HIGHLIGHTED; } else if (_journal.empty()) { color = COMMAND_NULL; @@ -883,9 +907,7 @@ bool Journal::handleEvents(int key) { screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), color, true, "Search"); // First Page button - if (pt.x > JOURNAL_POINTS[6][0] && pt.x < JOURNAL_POINTS[6][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) && - pt.y < (JOURNAL_BUTTONS_Y + 20) && _up) { - found = BTN_FIRST_PAGE; + if (btn == BTN_FIRST_PAGE) { color = COMMAND_HIGHLIGHTED; } else if (_up) { color = COMMAND_FOREGROUND; @@ -895,9 +917,7 @@ bool Journal::handleEvents(int key) { screen.buttonPrint(Common::Point(JOURNAL_POINTS[6][2], JOURNAL_BUTTONS_Y + 11), color, true, "First Page"); // Last Page button - if (pt.x > JOURNAL_POINTS[7][0] && pt.x < JOURNAL_POINTS[7][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) && - pt.y < (JOURNAL_BUTTONS_Y + 20) && _down) { - found = BTN_LAST_PAGE; + if (btn == BTN_LAST_PAGE) { color = COMMAND_HIGHLIGHTED; } else if (_down) { color = COMMAND_FOREGROUND; @@ -907,18 +927,14 @@ bool Journal::handleEvents(int key) { screen.buttonPrint(Common::Point(JOURNAL_POINTS[7][2], JOURNAL_BUTTONS_Y + 11), color, true, "Last Page"); // Print Text button - if (pt.x > JOURNAL_POINTS[8][0] && pt.x < JOURNAL_POINTS[8][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) && - pt.y < (JOURNAL_BUTTONS_Y + 20) && !_journal.empty()) { - found = BTN_PRINT_TEXT; - } screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11), COMMAND_NULL, true, "Print Text"); } - if (found == BTN_EXIT && events._released) { + if (btn == BTN_EXIT && events._released) { // Exit button pressed doneFlag = true; - } else if (((found == BTN_BACK10 && events._released) || key == 'B') && (_page > 1)) { + } else if (((btn == BTN_BACK10 && events._released) || key == 'B') && (_page > 1)) { // Scrolll up 10 pages if (_page < 11) drawJournal(1, (_page - 1) * LINES_PER_PAGE); @@ -928,19 +944,19 @@ bool Journal::handleEvents(int key) { doArrows(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); - } else if (((found == BTN_UP && events._released) || key == 'U') && _up) { + } else if (((btn == BTN_UP && events._released) || key == 'U') && _up) { // Scroll up drawJournal(1, LINES_PER_PAGE); doArrows(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); - } else if (((found == BTN_DOWN && events._released) || key == 'D') && _down) { + } else if (((btn == BTN_DOWN && events._released) || key == 'D') && _down) { // Scroll down drawJournal(2, LINES_PER_PAGE); doArrows(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); - } else if (((found == BTN_AHEAD110 && events._released) || key == 'A') && _down) { + } else if (((btn == BTN_AHEAD110 && events._released) || key == 'A') && _down) { // Scroll down 10 pages if ((_page + 10) > _maxPage) drawJournal(2, (_maxPage - _page) * LINES_PER_PAGE); @@ -950,7 +966,7 @@ bool Journal::handleEvents(int key) { doArrows(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); - } else if (((found == BTN_SEARCH && events._released) || key == 'S') && !_journal.empty()) { + } else if (((btn == BTN_SEARCH && events._released) || key == 'S') && !_journal.empty()) { screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), COMMAND_FOREGROUND, true, "Search"); bool notFound = false; @@ -981,7 +997,7 @@ bool Journal::handleEvents(int key) { } while (!doneFlag); doneFlag = false; - } else if (((found == BTN_FIRST_PAGE && events._released) || key == 'F') && _up) { + } else if (((btn == BTN_FIRST_PAGE && events._released) || key == 'F') && _up) { // First page _index = _sub = 0; _up = _down = false; @@ -992,7 +1008,7 @@ bool Journal::handleEvents(int key) { doArrows(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); - } else if (((found == BTN_LAST_PAGE && events._released) || key == 'L') && _down) { + } else if (((btn == BTN_LAST_PAGE && events._released) || key == 'L') && _down) { // Last page if ((_page + 10) > _maxPage) drawJournal(2, (_maxPage - _page) * LINES_PER_PAGE); diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h index 026579bac2..54bc9457cf 100644 --- a/engines/sherlock/journal.h +++ b/engines/sherlock/journal.h @@ -25,6 +25,7 @@ #include "common/scummsys.h" #include "common/array.h" +#include "common/rect.h" #include "common/serializer.h" #include "common/str-array.h" #include "common/stream.h" @@ -34,6 +35,12 @@ namespace Sherlock { #define JOURNAL_MAX_WIDTH 230 #define JOURNAL_MAX_CHARS 80 +enum JournalButton { + BTN_NONE, BTN_EXIT, BTN_BACK10, BTN_UP, BTN_DOWN, BTN_AHEAD110, BTN_SEARCH, + BTN_FIRST_PAGE, BTN_LAST_PAGE, BTN_PRINT_TEXT +}; + + struct JournalEntry { int _converseNum; bool _replyOnly; @@ -71,6 +78,8 @@ private: int getSearchString(bool printError); void drawJournalFrame(); + + JournalButton getHighlightedButton(const Common::Point &pt); public: Journal(SherlockEngine *vm); -- cgit v1.2.3 From 485214a831582bab79634555175a79a317039613 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 19 May 2015 00:03:54 -0400 Subject: SHERLOCK: Further addition of enums and method renames --- engines/sherlock/events.cpp | 10 ++++++---- engines/sherlock/inventory.cpp | 4 ++-- engines/sherlock/inventory.h | 2 +- engines/sherlock/user_interface.cpp | 4 ++-- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index 84794e6e6a..9d9c764fe5 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -30,6 +30,8 @@ namespace Sherlock { +enum ButtonFlag { LEFT_BUTTON = 1, RIGHT_BUTTON = 2 }; + Events::Events(SherlockEngine *vm) { _vm = vm; _cursorImages = nullptr; @@ -143,16 +145,16 @@ void Events::pollEvents() { case Common::EVENT_KEYUP: return; case Common::EVENT_LBUTTONDOWN: - _mouseButtons |= 1; + _mouseButtons |= LEFT_BUTTON; return; case Common::EVENT_RBUTTONDOWN: - _mouseButtons |= 2; + _mouseButtons |= RIGHT_BUTTON; return; case Common::EVENT_LBUTTONUP: - _mouseButtons &= ~1; + _mouseButtons &= ~LEFT_BUTTON; return; case Common::EVENT_RBUTTONUP: - _mouseButtons &= ~2; + _mouseButtons &= ~RIGHT_BUTTON; return; default: break; diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index d41e4b9b3e..2e7791e5f8 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -349,9 +349,9 @@ void Inventory::highlight(int index, byte color) { } /** - * Support method for updating the screen + * Support method for refreshing the display of the inventory */ -void Inventory::doInvJF() { +void Inventory::refreshInv() { Screen &screen = *_vm->_screen; Talk &talk = *_vm->_talk; UserInterface &ui = *_vm->_ui; diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index 979507a387..dd4c16b6c9 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -103,7 +103,7 @@ public: void highlight(int index, byte color); - void doInvJF(); + void refreshInv(); int putNameInInventory(const Common::String &name); int putItemInInventory(Object &obj); diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 1607c727eb..ef1da3b29f 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1198,7 +1198,7 @@ void UserInterface::doInvControl() { if ((mousePos.y < CONTROLS_Y1) && (inv._invMode == 1) && (_find >= 0) && (_find < 1000)) { if (!scene._bgShapes[_find]._examine.empty() && scene._bgShapes[_find]._examine[0] >= ' ') - inv.doInvJF(); + inv.refreshInv(); } else if (_selector != -1 || _find >= 0) { // Selector is the inventory object that was clicked on, or selected. // If it's -1, then no inventory item is highlighted yet. Otherwise, @@ -1206,7 +1206,7 @@ void UserInterface::doInvControl() { if (_selector != -1 && inv._invMode == INVMODE_LOOK && mousePos.y >(CONTROLS_Y1 + 11)) - inv.doInvJF(); + inv.refreshInv(); if (talk._talkToAbort) return; -- cgit v1.2.3 From 1e78908d170688e046cf18be841ee3c4aa41e53b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 19 May 2015 00:23:49 -0400 Subject: SHERLOCK: Replaced references to scene numbers with an enum --- engines/sherlock/map.cpp | 2 +- engines/sherlock/scalpel/scalpel.cpp | 43 ++++++++++++++++++------------------ engines/sherlock/scalpel/scalpel.h | 4 ++++ 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index 36c932d90d..2102f6ae51 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -63,7 +63,7 @@ Map::Map(SherlockEngine *vm) : _vm(vm), _topLine(SHERLOCK_SCREEN_WIDTH, 12) { _drawMap = false; _overPos = Common::Point(13000, 12600); _charPoint = 0; - _oldCharPoint = 39; + _oldCharPoint = 0; _frameChangeFlag = false; for (int idx = 0; idx < MAX_HOLMES_SEQUENCE; ++idx) diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index fa55ca6013..e47be791f0 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -254,6 +254,7 @@ void ScalpelEngine::initialize() { // Load the map co-ordinates for each scene and sequence data _map->loadPoints(NUM_PLACES, &MAP_X[0], &MAP_Y[0], &MAP_TRANSLATE[0]); _map->loadSequences(3, &MAP_SEQUENCES[0][0]); + _map->_oldCharPoint = BAKER_ST_EXTERIOR; } // Load the inventory @@ -553,7 +554,7 @@ void ScalpelEngine::showLBV(const Common::String &filename) { * Starting a scene within the game */ void ScalpelEngine::startScene() { - if (_scene->_goToScene == 100 || _scene->_goToScene == 98) { + if (_scene->_goToScene == OVERHEAD_MAP || _scene->_goToScene == OVERHEAD_MAP2) { // Show the map if (_sound->_musicOn) { if (_sound->loadSong(100)) { @@ -576,17 +577,17 @@ void ScalpelEngine::startScene() { // 55: Fade out and exit // 70: Brumwell suicide switch (_scene->_goToScene) { - case 2: - case 52: - case 53: - case 70: + case BLACKWOOD_CAPTURE: + case RESCUE_ANNA: + case MOOREHEAD_DEATH: + case BRUMWELL_SUICIDE: if (_sound->_musicOn && _sound->loadSong(_scene->_goToScene)) { if (_sound->_music) _sound->startSong(); } switch (_scene->_goToScene) { - case 2: + case BLACKWOOD_CAPTURE: // Blackwood's capture _res->addToCache("final2.vda", "epilogue.lib"); _res->addToCache("final2.vdx", "epilogue.lib"); @@ -594,7 +595,7 @@ void ScalpelEngine::startScene() { _animation->play("final2", 1, 0, false, 4); break; - case 52: + case RESCUE_ANNA: // Rescuing Anna _res->addToCache("finalr2.vda", "epilogue.lib"); _res->addToCache("finalr2.vdx", "epilogue.lib"); @@ -629,7 +630,7 @@ void ScalpelEngine::startScene() { _useEpilogue2 = false; break; - case 53: + case MOOREHEAD_DEATH: // Moorehead's death / subway train _res->addToCache("SUBWAY2.vda", "epilogue.lib"); _res->addToCache("SUBWAY2.vdx", "epilogue.lib"); @@ -645,7 +646,7 @@ void ScalpelEngine::startScene() { _screen->_fadeStyle = false; break; - case 70: + case BRUMWELL_SUICIDE: // Brumwell suicide _animation->play("suicid", 1, 3, true, 4); break; @@ -654,31 +655,31 @@ void ScalpelEngine::startScene() { } // Except for the Moorehead Murder scene, fade to black first - if (_scene->_goToScene != 53) { + if (_scene->_goToScene != MOOREHEAD_DEATH) { _events->wait(40); _screen->fadeToBlack(3); } switch (_scene->_goToScene) { case 52: - _scene->_goToScene = 27; // Go to the Lawyer's Office + _scene->_goToScene = LAWYER_OFFICE; // Go to the Lawyer's Office _map->_bigPos = Common::Point(0, 0); // Overland scroll position _map->_overPos = Common::Point(22900 - 600, 9400 + 900); // Overland position - _map->_oldCharPoint = 27; + _map->_oldCharPoint = LAWYER_OFFICE; break; case 53: - _scene->_goToScene = 17; // Go to St. Pancras Station + _scene->_goToScene = STATION; // Go to St. Pancras Station _map->_bigPos = Common::Point(0, 0); // Overland scroll position _map->_overPos = Common::Point(32500 - 600, 3000 + 900); // Overland position - _map->_oldCharPoint = 17; + _map->_oldCharPoint = STATION; break; default: - _scene->_goToScene = 4; // Back to Baker st. + _scene->_goToScene = BAKER_STREET; // Back to Baker st. _map->_bigPos = Common::Point(0, 0); // Overland scroll position _map->_overPos = Common::Point(14500 - 600, 8400 + 900); // Overland position - _map->_oldCharPoint = 4; + _map->_oldCharPoint = BAKER_STREET; break; } @@ -686,7 +687,7 @@ void ScalpelEngine::startScene() { _sound->freeSong(); break; - case 55: + case EXIT_GAME: // Exit game _screen->fadeToBlack(3); quitGame(); @@ -702,14 +703,14 @@ void ScalpelEngine::startScene() { if (_scene->_goToScene == 99) { // Darts Board minigame _darts->playDarts(); - _mapResult = _scene->_goToScene = 19; // Go back to the bar + _mapResult = _scene->_goToScene = PUB_INTERIOR; } _mapResult = _scene->_goToScene; } /** - * Takes care of clearing the mirror in scene 12, in case anything drew over it + * Takes care of clearing the mirror in scene 12 (mansion drawing room), in case anything drew over it */ void ScalpelEngine::eraseMirror12() { Common::Point pt((*_people)[AL]._position.x / 100, (*_people)[AL]._position.y / 100); @@ -722,7 +723,7 @@ void ScalpelEngine::eraseMirror12() { } /** - * Takes care of drawing Holme's reflection onto the mirror in scene 12 + * Takes care of drawing Holme's reflection onto the mirror in scene 12 (mansion drawing room) */ void ScalpelEngine::doMirror12() { People &people = *_people; @@ -798,7 +799,7 @@ void ScalpelEngine::doMirror12() { } /** - * This clears the mirror in scene 12 in case anything messed draw over it + * This clears the mirror in scene 12 (mansion drawing room) in case anything messed draw over it */ void ScalpelEngine::flushMirror12() { Common::Point pt((*_people)[AL]._position.x / 100, (*_people)[AL]._position.y / 100); diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h index 40e4937b5d..62875f1e90 100644 --- a/engines/sherlock/scalpel/scalpel.h +++ b/engines/sherlock/scalpel/scalpel.h @@ -30,6 +30,10 @@ namespace Sherlock { namespace Scalpel { +enum { BLACKWOOD_CAPTURE = 2, BAKER_STREET = 4, DRAWING_ROOM = 12, STATION = 17, PUB_INTERIOR = 19, + LAWYER_OFFICE = 27, BAKER_ST_EXTERIOR = 39, RESCUE_ANNA = 52, MOOREHEAD_DEATH = 53, EXIT_GAME = 55, + BRUMWELL_SUICIDE = 70, OVERHEAD_MAP2 = 98, DARTS_GAME = 99, OVERHEAD_MAP = 100 }; + class ScalpelEngine : public SherlockEngine { private: Darts *_darts; -- cgit v1.2.3 From 66f98c794cab091858954ee71a9b7680e4d6ef38 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 19 May 2015 00:26:23 -0400 Subject: SHERLOCK: Remove GCC_PRINTF to fix gcc compilation There are simply too many places that simply pass a string directly to the print methods rather than a format string --- engines/sherlock/screen.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 452a18631f..2103588fe0 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -101,8 +101,8 @@ public: void verticalTransition(); - void print(const Common::Point &pt, byte color, const char *formatStr, ...) GCC_PRINTF(4, 5); - void gPrint(const Common::Point &pt, byte color, const char *formatStr, ...) GCC_PRINTF(4, 5); + void print(const Common::Point &pt, byte color, const char *formatStr, ...); + void gPrint(const Common::Point &pt, byte color, const char *formatStr, ...); void restoreBackground(const Common::Rect &r); -- cgit v1.2.3 From 0faf1c0b8f5c52cde1addae3e14469fc5fa9b9a2 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 19 May 2015 00:28:59 -0400 Subject: SHERLOCK: Remove unused typedef --- engines/sherlock/map.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index 2102f6ae51..9b901e59f6 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -286,7 +286,6 @@ void Map::setupSprites() { Events &events = *_vm->_events; People &people = *_vm->_people; Scene &scene = *_vm->_scene; - typedef byte Sequences[16][MAX_FRAME]; _savedPos.x = -1; _mapCursors = new ImageFile("omouse.vgs"); -- cgit v1.2.3 From 1df183ffcb08a69ed414afd69284a0596fee4e82 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 19 May 2015 07:37:55 -0400 Subject: SHERLOCK: Move method comments from cpp to headers --- engines/sherlock/animation.cpp | 18 ---- engines/sherlock/animation.h | 21 ++++- engines/sherlock/debugger.cpp | 6 -- engines/sherlock/debugger.h | 6 ++ engines/sherlock/detection.cpp | 53 +++++------ engines/sherlock/events.cpp | 62 ------------- engines/sherlock/events.h | 63 ++++++++++++++ engines/sherlock/inventory.cpp | 52 ----------- engines/sherlock/inventory.h | 53 +++++++++++ engines/sherlock/journal.cpp | 40 --------- engines/sherlock/journal.h | 40 +++++++++ engines/sherlock/map.cpp | 54 ------------ engines/sherlock/map.h | 59 +++++++++++++ engines/sherlock/objects.cpp | 65 -------------- engines/sherlock/objects.h | 83 ++++++++++++++++++ engines/sherlock/people.cpp | 38 -------- engines/sherlock/people.h | 42 +++++++++ engines/sherlock/resources.cpp | 164 +++++++++++------------------------ engines/sherlock/resources.h | 66 ++++++++++++++ engines/sherlock/saveload.cpp | 40 --------- engines/sherlock/saveload.h | 44 ++++++++++ engines/sherlock/scalpel/darts.cpp | 52 ----------- engines/sherlock/scalpel/darts.h | 58 +++++++++++++ engines/sherlock/scalpel/scalpel.cpp | 42 +-------- engines/sherlock/scalpel/scalpel.h | 47 ++++++++++ engines/sherlock/scene.cpp | 99 --------------------- engines/sherlock/scene.h | 101 ++++++++++++++++++++- engines/sherlock/screen.cpp | 96 -------------------- engines/sherlock/screen.h | 100 +++++++++++++++++++++ engines/sherlock/settings.cpp | 13 --- engines/sherlock/settings.h | 12 +++ engines/sherlock/sherlock.cpp | 45 ---------- engines/sherlock/sherlock.h | 69 ++++++++++++++- engines/sherlock/sound.cpp | 3 - engines/sherlock/sound.h | 42 +++++++++ engines/sherlock/surface.cpp | 31 ------- engines/sherlock/surface.h | 37 ++++++++ engines/sherlock/talk.cpp | 75 ---------------- engines/sherlock/talk.h | 85 ++++++++++++++++++ engines/sherlock/user_interface.cpp | 94 -------------------- engines/sherlock/user_interface.h | 106 ++++++++++++++++++++++ 41 files changed, 1205 insertions(+), 1071 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 8b891125cc..21d63633d3 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -31,9 +31,6 @@ static const int NO_FRAMES = FRAMES_END; Animation::Animation(SherlockEngine *vm) : _vm(vm) { } -/** - * Play a full-screen animation - */ bool Animation::play(const Common::String &filename, int minDelay, int fade, bool setPalette, int speed) { Events &events = *_vm->_events; @@ -136,18 +133,12 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade, return !skipped && !_vm->shouldQuit(); } -/** - * Load the prologue name array - */ void Animation::setPrologueNames(const char *const *names, int count) { for (int idx = 0; idx < count; ++idx, ++names) { _prologueNames.push_back(*names); } } -/** - * Load the prologue frame array - */ void Animation::setPrologueFrames(const int *frames, int count, int maxFrames) { _prologueFrames.resize(count); @@ -157,18 +148,12 @@ void Animation::setPrologueFrames(const int *frames, int count, int maxFrames) { } } -/** - * Load the title name array - */ void Animation::setTitleNames(const char *const *names, int count) { for (int idx = 0; idx < count; ++idx, ++names) { _titleNames.push_back(*names); } } -/** - * Load the title frame array - */ void Animation::setTitleFrames(const int *frames, int count, int maxFrames) { _titleFrames.resize(count); @@ -178,9 +163,6 @@ void Animation::setTitleFrames(const int *frames, int count, int maxFrames) { } } -/** - * Checks for whether an animation is being played that has associated sound - */ const int *Animation::checkForSoundFrames(const Common::String &filename) { const int *frames = &NO_FRAMES; diff --git a/engines/sherlock/animation.h b/engines/sherlock/animation.h index 2c47686efd..b7811d3fa8 100644 --- a/engines/sherlock/animation.h +++ b/engines/sherlock/animation.h @@ -39,10 +39,12 @@ private: Common::Array _prologueNames; Common::Array > _prologueFrames; - Common::Array _titleNames; Common::Array > _titleFrames; + /** + * Checks for whether an animation is being played that has associated sound + */ const int *checkForSoundFrames(const Common::String &filename); public: Common::String _soundLibraryFilename; @@ -50,12 +52,29 @@ public: public: Animation(SherlockEngine *vm); + /** + * Load the prologue name array + */ void setPrologueNames(const char *const *names, int count); + + /** + * Load the prologue frame array + */ void setPrologueFrames(const int *frames, int count, int maxFrames); + /** + * Load the title name array + */ void setTitleNames(const char *const *names, int count); + + /** + * Load the title frame array + */ void setTitleFrames(const int *frames, int count, int maxFrames); + /** + * Play a full-screen animation + */ bool play(const Common::String &filename, int minDelay, int fade, bool setPalette, int speed); }; diff --git a/engines/sherlock/debugger.cpp b/engines/sherlock/debugger.cpp index ecd3f2ee08..cfbea2bc24 100644 --- a/engines/sherlock/debugger.cpp +++ b/engines/sherlock/debugger.cpp @@ -30,9 +30,6 @@ Debugger::Debugger(SherlockEngine *vm) : GUI::Debugger(), _vm(vm) { registerCmd("scene", WRAP_METHOD(Debugger, cmdScene)); } -/** - * Converts a decimal or hexadecimal string into a number - */ int Debugger::strToInt(const char *s) { if (!*s) // No string at all @@ -49,9 +46,6 @@ int Debugger::strToInt(const char *s) { return (int)tmp; } -/** - * Switch to another scene - */ bool Debugger::cmdScene(int argc, const char **argv) { if (argc != 2) { debugPrintf("Format: scene \n"); diff --git a/engines/sherlock/debugger.h b/engines/sherlock/debugger.h index 6021bb7d0d..e6a3aba828 100644 --- a/engines/sherlock/debugger.h +++ b/engines/sherlock/debugger.h @@ -34,8 +34,14 @@ class Debugger : public GUI::Debugger { private: SherlockEngine *_vm; + /** + * Converts a decimal or hexadecimal string into a number + */ int strToInt(const char *s); + /** + * Switch to another scene + */ bool cmdScene(int argc, const char **argv); public: Debugger(SherlockEngine *vm); diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp index 096eb9f46e..da3ad4628f 100644 --- a/engines/sherlock/detection.cpp +++ b/engines/sherlock/detection.cpp @@ -36,16 +36,10 @@ struct SherlockGameDescription { GameType gameID; }; -/** - * Returns the Id of the game - */ GameType SherlockEngine::getGameID() const { return _gameDescription->gameID; } -/** - * Returns the platform the game's datafiles are for - */ Common::Platform SherlockEngine::getPlatform() const { return _gameDescription->desc.platform; } @@ -135,17 +129,37 @@ public: return "Sherlock Engine (C) 1992-1996 Mythos Software, 1992-1996 (C) Electronic Arts"; } + /** + * Creates an instance of the game engine + */ virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; + + /** + * Returns a list of features the game's MetaEngine support + */ virtual bool hasFeature(MetaEngineFeature f) const; + + /** + * Return a list of savegames + */ virtual SaveStateList listSaves(const char *target) const; + + /** + * Returns the maximum number of allowed save slots + */ virtual int getMaximumSaveSlot() const; + + /** + * Deletes a savegame in the specified slot + */ virtual void removeSaveState(const char *target, int slot) const; + + /** + * Given a specified savegame slot, returns extended information for the save + */ SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const; }; -/** - * Creates an instance of the game engine - */ bool SherlockMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { const Sherlock::SherlockGameDescription *gd = (const Sherlock::SherlockGameDescription *)desc; if (gd) { @@ -164,9 +178,6 @@ bool SherlockMetaEngine::createInstance(OSystem *syst, Engine **engine, const AD return gd != 0; } -/** - * Returns a list of features the game's MetaEngine support - */ bool SherlockMetaEngine::hasFeature(MetaEngineFeature f) const { return (f == kSupportsListSaves) || @@ -176,9 +187,6 @@ bool SherlockMetaEngine::hasFeature(MetaEngineFeature f) const { (f == kSavesSupportThumbnail); } -/** - * Returns a list of features the game itself supports - */ bool Sherlock::SherlockEngine::hasFeature(EngineFeature f) const { return (f == kSupportsRTL) || @@ -186,38 +194,23 @@ bool Sherlock::SherlockEngine::hasFeature(EngineFeature f) const { (f == kSupportsSavingDuringRuntime); } -/** - * Returns whether the version is a demo - */ bool Sherlock::SherlockEngine::isDemo() const { return _gameDescription->desc.flags & ADGF_DEMO; } -/** - * Return a list of savegames - */ SaveStateList SherlockMetaEngine::listSaves(const char *target) const { return Sherlock::SaveManager::getSavegameList(target); } -/** - * Returns the maximum number of allowed save slots - */ int SherlockMetaEngine::getMaximumSaveSlot() const { return MAX_SAVEGAME_SLOTS; } -/** - * Deletes a savegame in the specified slot - */ void SherlockMetaEngine::removeSaveState(const char *target, int slot) const { Common::String filename = Sherlock::SaveManager(nullptr, target).generateSaveName(slot); g_system->getSavefileManager()->removeSavefile(filename); } -/** - * Given a specified savegame slot, returns extended information for the save - */ SaveStateDescriptor SherlockMetaEngine::querySaveMetaInfos(const char *target, int slot) const { Common::String filename = Sherlock::SaveManager(nullptr, target).generateSaveName(slot); Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(filename); diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index 9d9c764fe5..38093a6c72 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -48,9 +48,6 @@ Events::~Events() { delete _cursorImages; } -/** - * Load a set of cursors from the specified file - */ void Events::loadCursors(const Common::String &filename) { hideCursor(); delete _cursorImages; @@ -59,9 +56,6 @@ void Events::loadCursors(const Common::String &filename) { _cursorId = INVALID_CURSOR; } -/** - * Set the cursor to show - */ void Events::setCursor(CursorId cursorId) { if (cursorId == _cursorId) return; @@ -74,53 +68,31 @@ void Events::setCursor(CursorId cursorId) { setCursor(s); } -/** - * Set the cursor to show from a passed frame - */ void Events::setCursor(const Graphics::Surface &src) { CursorMan.replaceCursor(src.getPixels(), src.w, src.h, 0, 0, 0xff); showCursor(); } -/** - * Show the mouse cursor - */ void Events::showCursor() { CursorMan.showMouse(true); } -/** - * Hide the mouse cursor - */ void Events::hideCursor() { CursorMan.showMouse(false); } -/** - * Returns the cursor - */ CursorId Events::getCursor() const { return _cursorId; } -/** - * Returns true if the mouse cursor is visible - */ bool Events::isCursorVisible() const { return CursorMan.isVisible(); } -/** - * Move the mouse - */ void Events::moveMouse(const Common::Point &pt) { g_system->warpMouse(pt.x, pt.y); } - -/** - * Check for any pending events - */ void Events::pollEvents() { checkForNextFrameCounter(); @@ -162,18 +134,11 @@ void Events::pollEvents() { } } -/** - * Poll for events and introduce a small delay, to allow the system to - * yield to other running programs - */ void Events::pollEventsAndWait() { pollEvents(); g_system->delayMillis(10); } -/** - * Check whether it's time to display the next screen frame - */ bool Events::checkForNextFrameCounter() { // Check for next game frame uint32 milli = g_system->getMillis(); @@ -193,23 +158,14 @@ bool Events::checkForNextFrameCounter() { return false; } -/** - * Get the current mouse position - */ Common::Point Events::mousePos() const { return g_system->getEventManager()->getMousePos(); } -/** - * Get a pending keypress - */ Common::KeyState Events::getKey() { return _pendingKeys.pop(); } -/** - * Clear any current keypress or mouse click - */ void Events::clearEvents() { _pendingKeys.clear(); _mouseButtons = 0; @@ -218,24 +174,15 @@ void Events::clearEvents() { _oldButtons = _oldRightButton = false; } -/** - * Clear any pending keyboard inputs - */ void Events::clearKeyboard() { _pendingKeys.clear(); } -/** - * Delay for a given number of game frames, where each frame is 1/60th of a second - */ void Events::wait(int numFrames) { uint32 totalMilli = numFrames * 1000 / GAME_FRAME_RATE; delay(totalMilli); } -/** - * Does a delay of the specified number of milliseconds - */ bool Events::delay(uint32 time, bool interruptable) { // Different handling for really short versus extended times if (time < 10) { @@ -265,12 +212,6 @@ bool Events::delay(uint32 time, bool interruptable) { } } -/** - * Sets the pressed and released button flags on the raw button state previously set in pollEvents calls. - * @remarks The events manager has separate variables for the raw immediate and old button state - * versus the current buttons states for the frame. This method is expected to be called only once - * per game frame - */ void Events::setButtonState() { _released = _rightReleased = false; if (_mouseButtons & 1) @@ -290,9 +231,6 @@ void Events::setButtonState() { } } -/** - * Checks to see to see if a key or a mouse button is pressed. - */ bool Events::checkInput() { setButtonState(); return kbHit() || _pressed || _released || _rightPressed || _rightReleased; diff --git a/engines/sherlock/events.h b/engines/sherlock/events.h index c6d155e472..c19a92de8c 100644 --- a/engines/sherlock/events.h +++ b/engines/sherlock/events.h @@ -45,6 +45,9 @@ private: ImageFile *_cursorImages; int _mouseButtons; + /** + * Check whether it's time to display the next screen frame + */ bool checkForNextFrameCounter(); public: CursorId _cursorId; @@ -59,42 +62,102 @@ public: Events(SherlockEngine *vm); ~Events(); + /** + * Load a set of cursors from the specified file + */ void loadCursors(const Common::String &filename); + /** + * Set the cursor to show + */ void setCursor(CursorId cursorId); + + /** + * Set the cursor to show from a passed frame + */ void setCursor(const Graphics::Surface &src); + /** + * Show the mouse cursor + */ void showCursor(); + /** + * Hide the mouse cursor + */ void hideCursor(); + /** + * Returns the cursor + */ CursorId getCursor() const; + /** + * Returns true if the mouse cursor is visible + */ bool isCursorVisible() const; + /** + * Move the mouse + */ void moveMouse(const Common::Point &pt); + /** + * Check for any pending events + */ void pollEvents(); + /** + * Poll for events and introduce a small delay, to allow the system to + * yield to other running programs + */ void pollEventsAndWait(); + /** + * Get the current mouse position + */ Common::Point mousePos() const; uint32 getFrameCounter() const { return _frameCounter; } bool kbHit() const { return !_pendingKeys.empty(); } + /** + * Get a pending keypress + */ Common::KeyState getKey(); + /** + * Clear any current keypress or mouse click + */ void clearEvents(); + + /** + * Clear any pending keyboard inputs + */ void clearKeyboard(); + /** + * Delay for a given number of game frames, where each frame is 1/60th of a second + */ void wait(int numFrames); + /** + * Does a delay of the specified number of milliseconds + */ bool delay(uint32 time, bool interruptable = false); + /** + * Sets the pressed and released button flags on the raw button state previously set in pollEvents calls. + * @remarks The events manager has separate variables for the raw immediate and old button state + * versus the current buttons states for the frame. This method is expected to be called only once + * per game frame + */ void setButtonState(); + /** + * Checks to see to see if a key or a mouse button is pressed. + */ bool checkInput(); }; diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index 2e7791e5f8..28065a1b72 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -31,9 +31,6 @@ InventoryItem::InventoryItem(int requiredFlag, const Common::String &name, _examine(examine), _lookFlag(0) { } -/** - * Synchronize the data for an inventory item - */ void InventoryItem::synchronize(Common::Serializer &s) { s.syncAsSint16LE(_requiredFlag); s.syncAsSint16LE(_lookFlag); @@ -56,9 +53,6 @@ Inventory::~Inventory() { freeGraphics(); } -/** - * Free inventory data - */ void Inventory::freeInv() { freeGraphics(); @@ -66,9 +60,6 @@ void Inventory::freeInv() { _invGraphicsLoaded = false; } -/** - * Free any loaded inventory graphics - */ void Inventory::freeGraphics() { for (uint idx = 0; idx < MAX_VISIBLE_INVENTORY; ++idx) delete _invShapes[idx]; @@ -77,10 +68,6 @@ void Inventory::freeGraphics() { _invGraphicsLoaded = false; } -/** - * Load the list of names the inventory items correspond to, if not already loaded, - * and then calls loadGraphics to load the associated graphics - */ void Inventory::loadInv() { // Exit if the inventory names are already loaded if (_names.size() > 0) @@ -104,9 +91,6 @@ void Inventory::loadInv() { loadGraphics(); } -/** - * Load the list of names of graphics for the inventory - */ void Inventory::loadGraphics() { if (_invGraphicsLoaded) return; @@ -126,10 +110,6 @@ void Inventory::loadGraphics() { _invGraphicsLoaded = true; } -/** - * Searches through the list of names that correspond to the inventory items - * and returns the number that matches the passed name - */ int Inventory::findInv(const Common::String &name) { for (int idx = 0; idx < (int)_names.size(); ++idx) { if (name.equalsIgnoreCase(_names[idx])) @@ -140,9 +120,6 @@ int Inventory::findInv(const Common::String &name) { error("Couldn't find inventory item - %s", name.c_str()); } -/** - * Display the character's inventory. The slamIt parameter specifies: - */ void Inventory::putInv(InvSlamMode slamIt) { Screen &screen = *_vm->_screen; UserInterface &ui = *_vm->_ui; @@ -198,9 +175,6 @@ void Inventory::putInv(InvSlamMode slamIt) { } } -/** - * Put the game into inventory mode and open the interface window. - */ void Inventory::drawInventory(InvNewMode mode) { Screen &screen = *_vm->_screen; UserInterface &ui = *_vm->_ui; @@ -270,10 +244,6 @@ void Inventory::drawInventory(InvNewMode mode) { ui._oldUse = -1; } -/** - * Prints the line of inventory commands at the top of an inventory window with - * the correct highlighting - */ void Inventory::invCommands(bool slamIt) { Screen &screen = *_vm->_screen; UserInterface &ui = *_vm->_ui; @@ -333,9 +303,6 @@ void Inventory::invCommands(bool slamIt) { } } -/** - * Set the highlighting color of a given inventory item - */ void Inventory::highlight(int index, byte color) { Screen &screen = *_vm->_screen; Surface &bb = *screen._backBuffer; @@ -348,9 +315,6 @@ void Inventory::highlight(int index, byte color) { screen.slamArea(8 + slot * 52, 165, 44, 30); } -/** - * Support method for refreshing the display of the inventory - */ void Inventory::refreshInv() { Screen &screen = *_vm->_screen; Talk &talk = *_vm->_talk; @@ -373,9 +337,6 @@ void Inventory::refreshInv() { } } -/** - * Adds a shape from the scene to the player's inventory - */ int Inventory::putNameInInventory(const Common::String &name) { Scene &scene = *_vm->_scene; int matches = 0; @@ -391,10 +352,6 @@ int Inventory::putNameInInventory(const Common::String &name) { return matches; } -/** - * Moves a specified item into the player's inventory If the item has a *PICKUP* use action, - * then the item in the use action are added to the inventory. - */ int Inventory::putItemInInventory(Object &obj) { Scene &scene = *_vm->_scene; int matches = 0; @@ -456,9 +413,6 @@ int Inventory::putItemInInventory(Object &obj) { return matches; } -/** - * Copy the passed object into the inventory - */ void Inventory::copyToInventory(Object &obj) { InventoryItem invItem; invItem._name = obj._name; @@ -471,9 +425,6 @@ void Inventory::copyToInventory(Object &obj) { ++_holdings; } -/** - * Deletes a specified item from the player's inventory - */ int Inventory::deleteItemFromInventory(const Common::String &name) { int invNum = -1; @@ -493,9 +444,6 @@ int Inventory::deleteItemFromInventory(const Common::String &name) { return 1; } -/** - * Synchronize the data for a savegame - */ void Inventory::synchronize(Common::Serializer &s) { s.syncAsSint16LE(_holdings); diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index dd4c16b6c9..02f570f5da 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -66,6 +66,9 @@ struct InventoryItem { InventoryItem(int requiredFlag, const Common::String &name, const Common::String &description, const Common::String &examine); + /** + * Synchronize the data for an inventory item + */ void synchronize(Common::Serializer &s); }; @@ -74,6 +77,9 @@ private: SherlockEngine *_vm; Common::StringArray _names; + /** + * Copy the passed object into the inventory + */ void copyToInventory(Object &obj); public: ImageFile *_invShapes[MAX_VISIBLE_INVENTORY]; @@ -82,34 +88,81 @@ public: int _invIndex; int _holdings; // Used to hold number of visible items in active inventory. // Since Inventory array also contains some special hidden items + /** + * Free any loaded inventory graphics + */ void freeGraphics(); public: Inventory(SherlockEngine *vm); ~Inventory(); + /** + * Free inventory data + */ void freeInv(); + /** + * Load the list of names the inventory items correspond to, if not already loaded, + * and then calls loadGraphics to load the associated graphics + */ void loadInv(); + /** + * Load the list of names of graphics for the inventory + */ void loadGraphics(); + /** + * Searches through the list of names that correspond to the inventory items + * and returns the number that matches the passed name + */ int findInv(const Common::String &name); + /** + * Display the character's inventory. The slamIt parameter specifies: + */ void putInv(InvSlamMode slamIt); + /** + * Put the game into inventory mode and open the interface window. + */ void drawInventory(InvNewMode flag); + /** + * Prints the line of inventory commands at the top of an inventory window with + * the correct highlighting + */ void invCommands(bool slamIt); + /** + * Set the highlighting color of a given inventory item + */ void highlight(int index, byte color); + /** + * Support method for refreshing the display of the inventory + */ void refreshInv(); + /** + * Adds a shape from the scene to the player's inventory + */ int putNameInInventory(const Common::String &name); + + /** + * Moves a specified item into the player's inventory If the item has a *PICKUP* use action, + * then the item in the use action are added to the inventory. + */ int putItemInInventory(Object &obj); + /** + * Deletes a specified item from the player's inventory + */ int deleteItemFromInventory(const Common::String &name); + /** + * Synchronize the data for a savegame + */ void synchronize(Common::Serializer &s); }; diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 34a58b5871..0a0144996d 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -67,10 +67,6 @@ Journal::Journal(SherlockEngine *vm) : _vm(vm) { } } -/** - * Records statements that are said, in the order which they are said. The player - * can then read the journal to review them - */ void Journal::record(int converseNum, int statementNum, bool replyOnly) { int saveIndex = _index; int saveSub = _sub; @@ -96,9 +92,6 @@ void Journal::record(int converseNum, int statementNum, bool replyOnly) { } } -/** - * Load the list of location names that the journal will make reference to - */ void Journal::loadJournalLocations() { Resources &res = *_vm->_res; @@ -137,12 +130,6 @@ void Journal::loadJournalLocations() { delete loc; } -/** - * Loads the description for the current display index in the journal, and then - * word wraps the result to prepare it for being displayed - * @param alreadyLoaded Indicates whether the journal file is being loaded for the - * first time, or being reloaded - */ void Journal::loadJournalFile(bool alreadyLoaded) { Screen &screen = *_vm->_screen; Talk &talk = *_vm->_talk; @@ -459,9 +446,6 @@ void Journal::loadJournalFile(bool alreadyLoaded) { } } -/** - * Draw the journal background, frame, and interface buttons - */ void Journal::drawJournalFrame() { Resources &res = *_vm->_res; Screen &screen = *_vm->_screen; @@ -516,9 +500,6 @@ void Journal::drawJournalFrame() { COMMAND_NULL, false, "Print Text"); } -/** - * Display the journal - */ void Journal::drawInterface() { Screen &screen = *_vm->_screen; @@ -536,9 +517,6 @@ void Journal::drawInterface() { screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } -/** - * Display the arrows that can be used to scroll up and down pages - */ void Journal::doArrows() { Screen &screen = *_vm->_screen; byte color; @@ -560,9 +538,6 @@ void Journal::doArrows() { screen.buttonPrint(Common::Point(JOURNAL_POINTS[6][2], JOURNAL_BUTTONS_Y + 11), color, false, "First Page"); } -/** - * Displays a page of the journal at the current index - */ bool Journal::drawJournal(int direction, int howFar) { Events &events = *_vm->_events; Screen &screen = *_vm->_screen; @@ -808,9 +783,6 @@ bool Journal::drawJournal(int direction, int howFar) { return direction >= 3 && searchSuccessful; } -/** - * Returns the button, if any, that is under the specified position - */ JournalButton Journal::getHighlightedButton(const Common::Point &pt) { if (pt.x > JOURNAL_POINTS[0][0] && pt.x < JOURNAL_POINTS[0][1] && pt.y >= JOURNAL_BUTTONS_Y && pt.y < (JOURNAL_BUTTONS_Y + 10)) @@ -851,9 +823,6 @@ JournalButton Journal::getHighlightedButton(const Common::Point &pt) { return BTN_NONE; } -/** - * Handle events whilst the journal is being displayed - */ bool Journal::handleEvents(int key) { Events &events = *_vm->_events; Screen &screen = *_vm->_screen; @@ -1024,9 +993,6 @@ bool Journal::handleEvents(int key) { return doneFlag; } -/** - * Show the search submenu and allow the player to enter a search string - */ int Journal::getSearchString(bool printError) { enum Button { BTN_NONE, BTN_EXIT, BTN_BACKWARD, BTN_FORWARD }; @@ -1193,17 +1159,11 @@ int Journal::getSearchString(bool printError) { return done; } -/** - * Reset viewing position to the start of the journal - */ void Journal::resetPosition() { _index = _sub = _up = _down = 0; _page = 1; } -/** - * Synchronize the data for a savegame - */ void Journal::synchronize(Common::Serializer &s) { s.syncAsSint16LE(_index); s.syncAsSint16LE(_sub); diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h index 54bc9457cf..d62b8338c0 100644 --- a/engines/sherlock/journal.h +++ b/engines/sherlock/journal.h @@ -67,30 +67,70 @@ private: int _page; Common::String _find; + /** + * Load the list of location names that the journal will make reference to + */ void loadJournalLocations(); + /** + * Loads the description for the current display index in the journal, and then + * word wraps the result to prepare it for being displayed + * @param alreadyLoaded Indicates whether the journal file is being loaded for the + * first time, or being reloaded + */ void loadJournalFile(bool alreadyLoaded); + /** + * Display the arrows that can be used to scroll up and down pages + */ void doArrows(); + /** + * Displays a page of the journal at the current index + */ bool drawJournal(int direction, int howFar); + /** + * Show the search submenu and allow the player to enter a search string + */ int getSearchString(bool printError); + /** + * Draw the journal background, frame, and interface buttons + */ void drawJournalFrame(); + /** + * Returns the button, if any, that is under the specified position + */ JournalButton getHighlightedButton(const Common::Point &pt); public: Journal(SherlockEngine *vm); + /** + * Records statements that are said, in the order which they are said. The player + * can then read the journal to review them + */ void record(int converseNum, int statementNum, bool replyOnly = false); + /** + * Display the journal + */ void drawInterface(); + /** + * Handle events whilst the journal is being displayed + */ bool handleEvents(int key); + /** + * Reset viewing position to the start of the journal + */ void resetPosition(); + /** + * Synchronize the data for a savegame + */ void synchronize(Common::Serializer &s); }; diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index 9b901e59f6..737abb4895 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -25,9 +25,6 @@ namespace Sherlock { -/** - * Load the data for the paths between locations on the map - */ void MapPaths::load(int numLocations, Common::SeekableReadStream &s) { _numLocations = numLocations; _paths.resize(_numLocations * _numLocations); @@ -43,9 +40,6 @@ void MapPaths::load(int numLocations, Common::SeekableReadStream &s) { } } -/** - * Get the path between two locations on the map - */ const byte *MapPaths::getPath(int srcLocation, int destLocation) { return &_paths[srcLocation * _numLocations + destLocation][0]; } @@ -73,26 +67,17 @@ Map::Map(SherlockEngine *vm) : _vm(vm), _topLine(SHERLOCK_SCREEN_WIDTH, 12) { loadData(); } -/** - * Loads the list of points for locations on the map for each scene - */ void Map::loadPoints(int count, const int *xList, const int *yList, const int *transList) { for (int idx = 0; idx < count; ++idx, ++xList, ++yList, ++transList) { _points.push_back(MapEntry(*xList, *yList, *transList)); } } -/** - * Load the sequence data for player icon animations - */ void Map::loadSequences(int count, const byte *seq) { for (int idx = 0; idx < count; ++idx, seq += MAX_FRAME) Common::copy(seq, seq + MAX_FRAME, &_sequences[idx][0]); } -/** - * Load data needed for the map - */ void Map::loadData() { // Load the list of location names Common::SeekableReadStream *txtStream = _vm->_res->load("chess.txt"); @@ -125,9 +110,6 @@ void Map::loadData() { delete pathStream; } -/** - * Show the map - */ int Map::show() { Events &events = *_vm->_events; People &people = *_vm->_people; @@ -279,9 +261,6 @@ int Map::show() { return _charPoint; } -/** - * Load and initialize all the sprites that are needed for the map display - */ void Map::setupSprites() { Events &events = *_vm->_events; People &people = *_vm->_people; @@ -318,9 +297,6 @@ void Map::setupSprites() { scene._bgShapes.clear(); } -/** - * Free the sprites and data used by the map - */ void Map::freeSprites() { delete _mapCursors; delete _shapes; @@ -328,9 +304,6 @@ void Map::freeSprites() { _iconSave.free(); } -/** - * Draws an icon for every place that's currently known - */ void Map::showPlaces() { Screen &screen = *_vm->_screen; @@ -349,25 +322,16 @@ void Map::showPlaces() { } } -/** - * Makes a copy of the top rows of the screen that are used to display location names - */ void Map::saveTopLine() { _topLine.blitFrom(_vm->_screen->_backBuffer1, Common::Point(0, 0), Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, 12)); } -/** - * Erases anything shown in the top line by restoring the previously saved original map background - */ void Map::eraseTopLine() { Screen &screen = *_vm->_screen; screen._backBuffer1.blitFrom(_topLine, Common::Point(0, 0)); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, _topLine.h); } -/** - * Prints the name of the specified icon - */ void Map::showPlaceName(int idx, bool highlighted) { People &people = *_vm->_people; Screen &screen = *_vm->_screen; @@ -393,9 +357,6 @@ void Map::showPlaceName(int idx, bool highlighted) { } } -/** - * Update all on-screen sprites to account for any scrolling of the map - */ void Map::updateMap(bool flushScreen) { Events &events = *_vm->_events; People &people = *_vm->_people; @@ -442,9 +403,6 @@ void Map::updateMap(bool flushScreen) { } } -/** - * Handle moving icon for player from their previous location on the map to a destination location - */ void Map::walkTheStreets() { People &people = *_vm->_people; Common::Array tempPath; @@ -503,9 +461,6 @@ void Map::walkTheStreets() { people._walkTo.push(destPos); } -/** - * Save the area under the player's icon - */ void Map::saveIcon(ImageFrame *src, const Common::Point &pt) { Screen &screen = *_vm->_screen; Common::Point size(src->_width, src->_height); @@ -540,9 +495,6 @@ void Map::saveIcon(ImageFrame *src, const Common::Point &pt) { _savedSize = size; } -/** - * Restore the area under the player's icon - */ void Map::restoreIcon() { Screen &screen = *_vm->_screen; @@ -551,9 +503,6 @@ void Map::restoreIcon() { screen._backBuffer1.blitFrom(_iconSave, _savedPos, Common::Rect(0, 0, _savedSize.x, _savedSize.y)); } -/** - * Handles highlighting map icons, showing their names - */ void Map::highlightIcon(const Common::Point &pt) { int oldPoint = _point; @@ -592,9 +541,6 @@ void Map::highlightIcon(const Common::Point &pt) { } } -/** -* Synchronize the data for a savegame -*/ void Map::synchronize(Common::Serializer &s) { s.syncAsSint16LE(_bigPos.x); s.syncAsSint16LE(_bigPos.y); diff --git a/engines/sherlock/map.h b/engines/sherlock/map.h index 4a418138b2..2c8c02325b 100644 --- a/engines/sherlock/map.h +++ b/engines/sherlock/map.h @@ -49,8 +49,14 @@ private: int _numLocations; Common::Array< Common::Array > _paths; public: + /** + * Load the data for the paths between locations on the map + */ void load(int numLocations, Common::SeekableReadStream &s); + /** + * Get the path between two locations on the map + */ const byte *getPath(int srcLocation, int destLocation); }; @@ -75,24 +81,64 @@ private: bool _drawMap; Surface _iconSave; private: + /** + * Load data needed for the map + */ void loadData(); + /** + * Load and initialize all the sprites that are needed for the map display + */ void setupSprites(); + + /** + * Free the sprites and data used by the map + */ void freeSprites(); + /** + * Draws an icon for every place that's currently known + */ void showPlaces(); + /** + * Makes a copy of the top rows of the screen that are used to display location names + */ void saveTopLine(); + + /** + * Erases anything shown in the top line by restoring the previously saved original map background + */ void eraseTopLine(); + + /** + * Prints the name of the specified icon + */ void showPlaceName(int idx, bool highlighted); + /** + * Update all on-screen sprites to account for any scrolling of the map + */ void updateMap(bool flushScreen); + /** + * Handle moving icon for player from their previous location on the map to a destination location + */ void walkTheStreets(); + /** + * Save the area under the player's icon + */ void saveIcon(ImageFrame *src, const Common::Point &pt); + + /** + * Restore the area under the player's icon + */ void restoreIcon(); + /** + * Handles highlighting map icons, showing their names + */ void highlightIcon(const Common::Point &pt); public: bool _active; @@ -105,11 +151,24 @@ public: const MapEntry &operator[](int idx) { return _points[idx]; } + /** + * Loads the list of points for locations on the map for each scene + */ void loadPoints(int count, const int *xList, const int *yList, const int *transList); + + /** + * Load the sequence data for player icon animations + */ void loadSequences(int count, const byte *seq); + /** + * Show the map + */ int show(); + /** + * Synchronize the data for a savegame + */ void synchronize(Common::Serializer &s); }; diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index eb4676dd5f..e630b48f3a 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -41,9 +41,6 @@ namespace Sherlock { SherlockEngine *Sprite::_vm; -/** - * Reset the data for the sprite - */ void Sprite::clear() { _name = ""; _description = ""; @@ -68,18 +65,12 @@ void Sprite::clear() { _numFrames = 0; } -/** - * Updates the image frame poiner for the sprite - */ void Sprite::setImageFrame() { int imageNumber = (*_sequences)[_sequenceNumber][_frameNumber] + (*_sequences)[_sequenceNumber][0] - 2; _imageFrame = &(*_images)[imageNumber]; } -/** - * This adjusts the sprites position, as well as it's animation sequence: - */ void Sprite::adjustSprite() { Map &map = *_vm->_map; People &people = *_vm->_people; @@ -175,9 +166,6 @@ void Sprite::adjustSprite() { } } -/** - * Checks the sprite's position to see if it's collided with any special objects - */ void Sprite::checkSprite() { Events &events = *_vm->_events; People &people = *_vm->_people; @@ -364,9 +352,6 @@ void Sprite::checkSprite() { /*----------------------------------------------------------------*/ -/** - * Load the data for the action - */ void ActionType::load(Common::SeekableReadStream &s) { char buffer[12]; @@ -388,9 +373,6 @@ UseType::UseType() { _useFlag = 0; } -/** - * Load the data for the UseType - */ void UseType::load(Common::SeekableReadStream &s) { char buffer[12]; @@ -454,9 +436,6 @@ Object::Object() { _seqSize = 0; } -/** - * Load the data for the object - */ void Object::load(Common::SeekableReadStream &s) { char buffer[41]; s.read(buffer, 12); @@ -522,9 +501,6 @@ void Object::load(Common::SeekableReadStream &s) { _use[idx].load(s); } -/** - * Toggle the type of an object between hidden and active - */ void Object::toggleHidden() { if (_type != HIDDEN && _type != HIDE_SHAPE && _type != INVALID) { if (_seqTo != 0) @@ -560,9 +536,6 @@ void Object::toggleHidden() { } } -/** - * Check the state of the object - */ void Object::checkObject() { Scene &scene = *_vm->_scene; Sound &sound = *_vm->_sound; @@ -686,11 +659,6 @@ void Object::checkObject() { } while (codeFound); } -/** - * This will check to see if the object has reached the end of a sequence. - * If it has, it switch to whichever next sequence should be started. - * @returns true if the end of a sequence was reached - */ bool Object::checkEndOfSequence() { Screen &screen = *_vm->_screen; int checkFrame = _allow ? MAX_FRAME : FRAMES_END; @@ -743,10 +711,6 @@ bool Object::checkEndOfSequence() { return result; } -/** - * Scans through the sequences array and finds the designated sequence. - * It then sets the frame number of the start of that sequence - */ void Object::setObjSequence(int seq, bool wait) { Scene &scene = *_vm->_scene; int checkFrame = _allow ? MAX_FRAME : FRAMES_END; @@ -820,12 +784,6 @@ void Object::setObjSequence(int seq, bool wait) { } } -/** - * Checks for codes - * @param name The name to check for codes - * @param messages Provides a lookup list of messages that can be printed - * @returns 0 if no codes are found, 1 if codes were found - */ int Object::checkNameForCodes(const Common::String &name, const char *const messages[]) { Map &map = *_vm->_map; People &people = *_vm->_people; @@ -921,9 +879,6 @@ int Object::checkNameForCodes(const Common::String &name, const char *const mess return printed; } -/** - * Handle setting any flags associated with the object - */ void Object::setFlagsAndToggles() { Scene &scene = *_vm->_scene; Talk &talk = *_vm->_talk; @@ -949,10 +904,6 @@ void Object::setFlagsAndToggles() { } } -/** - * Adjusts the sprite's position and animation sequence, advancing by 1 frame. - * If the end of the sequence is reached, the appropriate action is taken. - */ void Object::adjustObject() { if (_type == REMOVE) return; @@ -975,10 +926,6 @@ void Object::adjustObject() { } } -/** - * Handles trying to pick up an object. If allowed, plays an y necessary animation for picking - * up the item, and then adds it to the player's inventory - */ int Object::pickUpObject(const char *const messages[]) { Inventory &inv = *_vm->_inventory; People &people = *_vm->_people; @@ -1065,9 +1012,6 @@ int Object::pickUpObject(const char *const messages[]) { return numObjects; } -/** - * Returns the current bounds for the sprite - */ const Common::Rect Object::getNewBounds() const { Common::Point pt = _position; if (_imageFrame) @@ -1076,17 +1020,11 @@ const Common::Rect Object::getNewBounds() const { return Common::Rect(pt.x, pt.y, pt.x + frameWidth(), pt.y + frameHeight()); } -/** - * Returns the bounds for a sprite without a shape - */ const Common::Rect Object::getNoShapeBounds() const { return Common::Rect(_position.x, _position.y, _position.x + _noShapeSize.x, _position.y + _noShapeSize.y); } -/** - * Returns the old bounsd for the sprite from the previous frame - */ const Common::Rect Object::getOldBounds() const { return Common::Rect(_oldPosition.x, _oldPosition.y, _oldPosition.x + _oldSize.x, _oldPosition.y + _oldSize.y); @@ -1094,9 +1032,6 @@ const Common::Rect Object::getOldBounds() const { /*----------------------------------------------------------------*/ -/** - * Load the data for the animation - */ void CAnim::load(Common::SeekableReadStream &s) { char buffer[12]; s.read(buffer, 12); diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index e3e07d89b7..53752a7351 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -129,15 +129,34 @@ public: Sprite() { clear(); } static void setVm(SherlockEngine *vm) { _vm = vm; } + /** + * Reset the data for the sprite + */ void clear(); + /** + * Updates the image frame poiner for the sprite + */ void setImageFrame(); + /** + * This adjusts the sprites position, as well as it's animation sequence: + */ void adjustSprite(); + /** + * Checks the sprite's position to see if it's collided with any special objects + */ void checkSprite(); + /** + * Return frame width + */ int frameWidth() const { return _imageFrame ? _imageFrame->_frame.w : 0; } + + /** + * Return frame height + */ int frameHeight() const { return _imageFrame ? _imageFrame->_frame.h : 0; } }; @@ -149,6 +168,9 @@ struct ActionType { int _cAnimSpeed; Common::String _names[NAMES_COUNT]; + /** + * Load the data for the action + */ void load(Common::SeekableReadStream &s); }; @@ -160,6 +182,10 @@ struct UseType { Common::String _target; UseType(); + + /** + * Load the data for the UseType + */ void load(Common::SeekableReadStream &s); }; @@ -170,8 +196,17 @@ class Object { private: static SherlockEngine *_vm; + /** + * This will check to see if the object has reached the end of a sequence. + * If it has, it switch to whichever next sequence should be started. + * @returns true if the end of a sequence was reached + */ bool checkEndOfSequence(); + /** + * Scans through the sequences array and finds the designated sequence. + * It then sets the frame number of the start of that sequence + */ void setObjSequence(int seq, bool wait); public: static bool _countCAnimFrames; @@ -224,24 +259,69 @@ public: Object(); + /** + * Load the data for the object + */ void load(Common::SeekableReadStream &s); + /** + * Toggle the type of an object between hidden and active + */ void toggleHidden(); + /** + * Check the state of the object + */ void checkObject(); + /** + * Checks for codes + * @param name The name to check for codes + * @param messages Provides a lookup list of messages that can be printed + * @returns 0 if no codes are found, 1 if codes were found + */ int checkNameForCodes(const Common::String &name, const char *const messages[]); + /** + * Handle setting any flags associated with the object + */ void setFlagsAndToggles(); + /** + * Adjusts the sprite's position and animation sequence, advancing by 1 frame. + * If the end of the sequence is reached, the appropriate action is taken. + */ void adjustObject(); + /** + * Handles trying to pick up an object. If allowed, plays an y necessary animation for picking + * up the item, and then adds it to the player's inventory + */ int pickUpObject(const char *const messages[]); + /** + * Return the frame width + */ int frameWidth() const { return _imageFrame ? _imageFrame->_frame.w : 0; } + + /** + * Return the frame height + */ int frameHeight() const { return _imageFrame ? _imageFrame->_frame.h : 0; } + + /** + * Returns the current bounds for the sprite + */ const Common::Rect getNewBounds() const; + + /** + * Returns the bounds for a sprite without a shape + */ const Common::Rect getNoShapeBounds() const; + + /** + * Returns the old bounsd for the sprite from the previous frame + */ const Common::Rect getOldBounds() const; }; @@ -257,6 +337,9 @@ struct CAnim { Common::Point _teleportPos; // Location Holmes shoul teleport to after int _teleportDir; // playing canim + /** + * Load the data for the animation + */ void load(Common::SeekableReadStream &s); }; diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index ad7c37a8c4..3a169fa99c 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -217,9 +217,6 @@ People::~People() { delete[] _portrait._sequences; } -/** - * Reset the player data - */ void People::reset() { // Note: The engine has theoretical support for two player characters but only the first one is used. // Watson is, instead, handled by a different sprite in each scene, with a very simple initial movement, if any @@ -247,9 +244,6 @@ void People::reset() { _walkTo.clear(); } -/** - * Load the walking images for Sherlock - */ bool People::loadWalk() { if (_walkLoaded) { return false; @@ -262,9 +256,6 @@ bool People::loadWalk() { } } -/** - * If the walk data has been loaded, then it will be freed - */ bool People::freeWalk() { if (_walkLoaded) { delete _player._images; @@ -277,11 +268,6 @@ bool People::freeWalk() { } } -/** - * Set the variables for moving a character from one poisition to another - * in a straight line - goAllTheWay must have been previously called to - * check for any obstacles in the path. - */ void People::setWalking() { Map &map = *_vm->_map; Scene &scene = *_vm->_scene; @@ -427,10 +413,6 @@ void People::setWalking() { _player._frameNumber = oldFrame; } -/** - * Bring a moving character to a standing position. If the Scalpel chessboard - * is being displayed, then the chraracter will always face down. - */ void People::gotoStand(Sprite &sprite) { Map &map = *_vm->_map; _walkTo.clear(); @@ -481,9 +463,6 @@ void People::gotoStand(Sprite &sprite) { _allowWalkAbort = true; } -/** - * Walk to the co-ordinates passed, and then face the given direction - */ void People::walkToCoords(const Common::Point &destPos, int destDir) { Events &events = *_vm->_events; Scene &scene = *_vm->_scene; @@ -516,11 +495,6 @@ void People::walkToCoords(const Common::Point &destPos, int destDir) { } } -/** - * Called to set the character walking to the current cursor location. - * It uses the zones and the inter-zone points to determine a series - * of steps to walk to get to that position. - */ void People::goAllTheWay() { Scene &scene = *_vm->_scene; Common::Point srcPt(_player._position.x / 100 + _player.frameWidth() / 2, @@ -608,9 +582,6 @@ void People::goAllTheWay() { } } -/** - * Finds the scene background object corresponding to a specified speaker - */ int People::findSpeaker(int speaker) { Scene &scene = *_vm->_scene; @@ -629,9 +600,6 @@ int People::findSpeaker(int speaker) { return -1; } -/** - * Turn off any currently active portraits, and removes them from being drawn - */ void People::clearTalking() { Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; @@ -662,9 +630,6 @@ void People::clearTalking() { } } -/** - * Setup the data for an animating speaker portrait at the top of the screen - */ void People::setTalking(int speaker) { Resources &res = *_vm->_res; @@ -724,9 +689,6 @@ void People::setTalking(int speaker) { } } -/** - * Synchronize the data for a savegame - */ void People::synchronize(Common::Serializer &s) { s.syncAsByte(_holmesOn); s.syncAsSint16LE(_player._position.x); diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index 9ac1a797c6..f22070f5f9 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -102,27 +102,69 @@ public: return _data[idx]; } + /** + * Returns true if Sherlock is visible on the screen and enabled + */ bool isHolmesActive() const { return _walkLoaded && _holmesOn; } + /** + * Reset the player data + */ void reset(); + /** + * Load the walking images for Sherlock + */ bool loadWalk(); + /** + * If the walk data has been loaded, then it will be freed + */ bool freeWalk(); + /** + * Set the variables for moving a character from one poisition to another + * in a straight line - goAllTheWay must have been previously called to + * check for any obstacles in the path. + */ void setWalking(); + /** + * Bring a moving character to a standing position. If the Scalpel chessboard + * is being displayed, then the chraracter will always face down. + */ void gotoStand(Sprite &sprite); + /** + * Walk to the co-ordinates passed, and then face the given direction + */ void walkToCoords(const Common::Point &destPos, int destDir); + /** + * Called to set the character walking to the current cursor location. + * It uses the zones and the inter-zone points to determine a series + * of steps to walk to get to that position. + */ void goAllTheWay(); + /** + * Finds the scene background object corresponding to a specified speaker + */ int findSpeaker(int speaker); + /** + * Turn off any currently active portraits, and removes them from being drawn + */ void clearTalking(); + + /** + * Setup the data for an animating speaker portrait at the top of the screen + */ void setTalking(int speaker); + /** + * Synchronize the data for a savegame + */ void synchronize(Common::Serializer &s); }; diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index 5a98d57011..091ef3ea12 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -31,18 +31,10 @@ namespace Sherlock { Cache::Cache(SherlockEngine *vm) : _vm(vm) { } -/** - * Returns true if a given file is currently being cached - */ bool Cache::isCached(const Common::String &filename) const { return _resources.contains(filename); } -/** - * Loads a file into the cache if it's not already present, and returns it. - * If the file is LZW compressed, automatically decompresses it and loads - * the uncompressed version into memory - */ void Cache::load(const Common::String &name) { // First check if the entry already exists if (_resources.contains(name)) @@ -58,9 +50,6 @@ void Cache::load(const Common::String &name) { f.close(); } -/** - * Load a cache entry based on a passed stream - */ void Cache::load(const Common::String &name, Common::SeekableReadStream &stream) { // First check if the entry already exists if (_resources.contains(name)) @@ -88,9 +77,6 @@ void Cache::load(const Common::String &name, Common::SeekableReadStream &stream) } } -/** - * Get a file from the cache - */ Common::SeekableReadStream *Cache::get(const Common::String &filename) const { // Return a memory stream that encapsulates the data const CacheEntry &cacheEntry = _resources[filename]; @@ -111,10 +97,6 @@ Resources::Resources(SherlockEngine *vm) : _vm(vm), _cache(vm) { } } -/** - * Adds the specified file to the cache. If it's a library file, takes care of - * loading it's index for future use - */ void Resources::addToCache(const Common::String &filename) { _cache.load(filename); @@ -127,9 +109,6 @@ void Resources::addToCache(const Common::String &filename) { delete stream; } -/** - * Adds a resource from a library file to the cache - */ void Resources::addToCache(const Common::String &filename, const Common::String &libFilename) { // Get the resource Common::SeekableReadStream *stream = load(filename, libFilename); @@ -139,16 +118,10 @@ void Resources::addToCache(const Common::String &filename, const Common::String delete stream; } -/** - * Adds a given stream to the cache under the given name - */ void Resources::addToCache(const Common::String &filename, Common::SeekableReadStream &stream) { _cache.load(filename, stream); } -/** - * Returns a stream for a given file - */ Common::SeekableReadStream *Resources::load(const Common::String &filename) { // First check if the file is directly in the cache if (_cache.isCached(filename)) @@ -184,9 +157,6 @@ Common::SeekableReadStream *Resources::load(const Common::String &filename) { return stream; } -/** - * Checks the passed stream, and if is compressed, deletes it and replaces it with it's uncompressed data - */ void Resources::decompressIfNecessary(Common::SeekableReadStream *&stream) { bool isCompressed = stream->readUint32BE() == MKTAG('L', 'Z', 'V', 26); stream->seek(-4, SEEK_CUR); @@ -198,9 +168,6 @@ void Resources::decompressIfNecessary(Common::SeekableReadStream *&stream) { } } -/** - * Loads a specific resource from a given library file - */ Common::SeekableReadStream *Resources::load(const Common::String &filename, const Common::String &libraryFile) { // Open up the library for access Common::SeekableReadStream *libStream = load(libraryFile); @@ -219,17 +186,11 @@ Common::SeekableReadStream *Resources::load(const Common::String &filename, cons return stream; } -/** - * Returns true if the given file exists on disk or in the cache - */ bool Resources::exists(const Common::String &filename) const { Common::File f; return f.exists(filename) || _cache.isCached(filename); } -/** - * Reads in the index from a library file, and caches it's index for later use - */ void Resources::loadLibraryIndex(const Common::String &libFilename, Common::SeekableReadStream *stream) { uint32 offset, nextOffset; @@ -266,15 +227,63 @@ void Resources::loadLibraryIndex(const Common::String &libFilename, } } -/** - * Returns the index of the last loaded resource in it's given library file. - * This will be used primarily when loading talk files, so the engine can - * update the given conversation number in the journal - */ int Resources::resourceIndex() const { return _resourceIndex; } +Common::SeekableReadStream *Resources::decompressLZ(Common::SeekableReadStream &source) { + if (_vm->getGameID() == GType_SerratedScalpel) { + uint32 id = source.readUint32BE(); + assert(id == MKTAG('L', 'Z', 'V', 0x1A)); + } + + uint32 size = source.readUint32LE(); + return decompressLZ(source, size); +} + +Common::SeekableReadStream *Resources::decompressLZ(Common::SeekableReadStream &source, uint32 outSize) { + byte lzWindow[4096]; + uint16 lzWindowPos; + uint16 cmd; + + byte *outBuffer = (byte *)malloc(outSize); + byte *outBufferEnd = outBuffer + outSize; + Common::MemoryReadStream *outS = new Common::MemoryReadStream(outBuffer, outSize, DisposeAfterUse::YES); + + memset(lzWindow, 0xFF, 0xFEE); + lzWindowPos = 0xFEE; + cmd = 0; + + do { + cmd >>= 1; + if (!(cmd & 0x100)) + cmd = source.readByte() | 0xFF00; + + if (cmd & 1) { + byte literal = source.readByte(); + *outBuffer++ = literal; + lzWindow[lzWindowPos] = literal; + lzWindowPos = (lzWindowPos + 1) & 0x0FFF; + } + else { + int copyPos, copyLen; + copyPos = source.readByte(); + copyLen = source.readByte(); + copyPos = copyPos | ((copyLen & 0xF0) << 4); + copyLen = (copyLen & 0x0F) + 3; + while (copyLen--) { + byte literal = lzWindow[copyPos]; + copyPos = (copyPos + 1) & 0x0FFF; + *outBuffer++ = literal; + lzWindow[lzWindowPos] = literal; + lzWindowPos = (lzWindowPos + 1) & 0x0FFF; + } + } + } while (outBuffer < outBufferEnd); + + return outS; +} + /*----------------------------------------------------------------*/ SherlockEngine *ImageFile::_vm; @@ -302,9 +311,6 @@ ImageFile::~ImageFile() { (*this)[idx]._frame.free(); } -/** - * Load the data of the sprite - */ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette, bool animImages) { loadPalette(stream); @@ -350,9 +356,6 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette, bool } } -/** - * Gets the palette at the start of the sprite file - */ void ImageFile::loadPalette(Common::SeekableReadStream &stream) { // Check for palette int v1 = stream.readUint16LE() + 1; @@ -372,9 +375,6 @@ void ImageFile::loadPalette(Common::SeekableReadStream &stream) { } } -/** - * Decompress a single frame for the sprite - */ void ImageFile::decompressFrame(ImageFrame &frame, const byte *src) { frame._frame.create(frame._width, frame._height, Graphics::PixelFormat::createFormatCLUT8()); @@ -411,62 +411,4 @@ void ImageFile::decompressFrame(ImageFrame &frame, const byte *src) { } } -/** - * Decompress an LZW compressed resource - */ -Common::SeekableReadStream *Resources::decompressLZ(Common::SeekableReadStream &source) { - if (_vm->getGameID() == GType_SerratedScalpel) { - uint32 id = source.readUint32BE(); - assert(id == MKTAG('L', 'Z', 'V', 0x1A)); - } - - uint32 size = source.readUint32LE(); - return decompressLZ(source, size); -} - -/** - * Decompresses an LZW block of data with a specified output size - */ -Common::SeekableReadStream *Resources::decompressLZ(Common::SeekableReadStream &source, uint32 outSize) { - byte lzWindow[4096]; - uint16 lzWindowPos; - uint16 cmd; - - byte *outBuffer = (byte *)malloc(outSize); - byte *outBufferEnd = outBuffer + outSize; - Common::MemoryReadStream *outS = new Common::MemoryReadStream(outBuffer, outSize, DisposeAfterUse::YES); - - memset(lzWindow, 0xFF, 0xFEE); - lzWindowPos = 0xFEE; - cmd = 0; - - do { - cmd >>= 1; - if (!(cmd & 0x100)) - cmd = source.readByte() | 0xFF00; - - if (cmd & 1) { - byte literal = source.readByte(); - *outBuffer++ = literal; - lzWindow[lzWindowPos] = literal; - lzWindowPos = (lzWindowPos + 1) & 0x0FFF; - } else { - int copyPos, copyLen; - copyPos = source.readByte(); - copyLen = source.readByte(); - copyPos = copyPos | ((copyLen & 0xF0) << 4); - copyLen = (copyLen & 0x0F) + 3; - while (copyLen--) { - byte literal = lzWindow[copyPos]; - copyPos = (copyPos + 1) & 0x0FFF; - *outBuffer++ = literal; - lzWindow[lzWindowPos] = literal; - lzWindowPos = (lzWindowPos + 1) & 0x0FFF; - } - } - } while (outBuffer < outBufferEnd); - - return outS; -} - } // End of namespace Sherlock diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h index 6bb0682f8d..4ca4038529 100644 --- a/engines/sherlock/resources.h +++ b/engines/sherlock/resources.h @@ -57,11 +57,26 @@ private: public: Cache(SherlockEngine *_vm); + /** + * Returns true if a given file is currently being cached + */ bool isCached(const Common::String &filename) const; + /** + * Loads a file into the cache if it's not already present, and returns it. + * If the file is LZW compressed, automatically decompresses it and loads + * the uncompressed version into memory + */ void load(const Common::String &name); + + /** + * Load a cache entry based on a passed stream + */ void load(const Common::String &name, Common::SeekableReadStream &stream); + /** + * Get a file from the cache + */ Common::SeekableReadStream *get(const Common::String &filename) const; }; @@ -72,26 +87,66 @@ private: LibraryIndexes _indexes; int _resourceIndex; + /** + * Reads in the index from a library file, and caches it's index for later use + */ void loadLibraryIndex(const Common::String &libFilename, Common::SeekableReadStream *stream); public: Resources(SherlockEngine *vm); + /** + * Adds the specified file to the cache. If it's a library file, takes care of + * loading it's index for future use + */ void addToCache(const Common::String &filename); + + /** + * Adds a resource from a library file to the cache + */ void addToCache(const Common::String &filename, const Common::String &libFilename); + + /** + * Adds a given stream to the cache under the given name + */ void addToCache(const Common::String &filename, Common::SeekableReadStream &stream); + bool isInCache(const Common::String &filename) const { return _cache.isCached(filename); } + /** + * Checks the passed stream, and if is compressed, deletes it and replaces it with it's uncompressed data + */ void decompressIfNecessary(Common::SeekableReadStream *&stream); + /** + * Returns a stream for a given file + */ Common::SeekableReadStream *load(const Common::String &filename); + /** + * Loads a specific resource from a given library file + */ Common::SeekableReadStream *load(const Common::String &filename, const Common::String &libraryFile); + /** + * Returns true if the given file exists on disk or in the cache + */ bool exists(const Common::String &filename) const; + /** + * Returns the index of the last loaded resource in it's given library file. + * This will be used primarily when loading talk files, so the engine can + * update the given conversation number in the journal + */ int resourceIndex() const; + /** + * Decompresses an LZW block of data with a specified output size + */ static Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source, uint32 outSize); + + /** + * Decompress an LZW compressed resource + */ Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source); }; @@ -111,8 +166,19 @@ class ImageFile : public Common::Array { private: static SherlockEngine *_vm; + /** + * Load the data of the sprite + */ void load(Common::SeekableReadStream &stream, bool skipPalette, bool animImages); + + /** + * Gets the palette at the start of the sprite file + */ void loadPalette(Common::SeekableReadStream &stream); + + /** + * Decompress a single frame for the sprite + */ void decompressFrame(ImageFrame &frame, const byte *src); public: byte _palette[256 * 3]; diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index 6fb1dcc448..bec832aa05 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -55,9 +55,6 @@ SaveManager::~SaveManager() { } } -/** - * Shows the in-game dialog interface for loading and saving games - */ void SaveManager::drawInterface() { Screen &screen = *_vm->_screen; UserInterface &ui = *_vm->_ui; @@ -107,9 +104,6 @@ void SaveManager::drawInterface() { _envMode = SAVEMODE_NONE; } -/** - * Build up a savegame list, with empty slots given an explicit Empty message - */ void SaveManager::createSavegameList() { Screen &screen = *_vm->_screen; @@ -137,9 +131,6 @@ void SaveManager::createSavegameList() { } } -/** - * Load a list of savegames - */ SaveStateList SaveManager::getSavegameList(const Common::String &target) { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); Common::StringArray filenames; @@ -175,9 +166,6 @@ SaveStateList SaveManager::getSavegameList(const Common::String &target) { const char *const SAVEGAME_STR = "SHLK"; #define SAVEGAME_STR_SIZE 4 -/** - * Read in the header information for a savegame - */ bool SaveManager::readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header) { char saveIdentBuffer[SAVEGAME_STR_SIZE + 1]; header._thumbnail = nullptr; @@ -212,9 +200,6 @@ bool SaveManager::readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHea return true; } -/** - * Write out the header information for a savegame - */ void SaveManager::writeSavegameHeader(Common::OutSaveFile *out, SherlockSavegameHeader &header) { // Write out a savegame header out->write(SAVEGAME_STR, SAVEGAME_STR_SIZE + 1); @@ -245,9 +230,6 @@ void SaveManager::writeSavegameHeader(Common::OutSaveFile *out, SherlockSavegame out->writeUint32LE(_vm->_events->getFrameCounter()); } -/** - * Creates a thumbnail for the current on-screen contents - */ void SaveManager::createThumbnail() { if (_saveThumb) { _saveThumb->free(); @@ -260,9 +242,6 @@ void SaveManager::createThumbnail() { ::createThumbnail(_saveThumb, (const byte *)_vm->_screen->getPixels(), SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT, thumbPalette); } -/** - * Return the index of the button the mouse is over, if any - */ int SaveManager::getHighlightedButton() const { Common::Point pt = _vm->_events->mousePos(); @@ -275,9 +254,6 @@ int SaveManager::getHighlightedButton() const { return -1; } -/** - * Handle highlighting buttons - */ void SaveManager::highlightButtons(int btnIndex) { Screen &screen = *_vm->_screen; byte color = (btnIndex == 0) ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND; @@ -309,9 +285,6 @@ void SaveManager::highlightButtons(int btnIndex) { screen.buttonPrint(Common::Point(ENV_POINTS[5][2], CONTROLS_Y), color, 1, "Quit"); } -/** - * Load the game in the specified slot - */ void SaveManager::loadGame(int slot) { Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading( generateSaveName(slot)); @@ -335,9 +308,6 @@ void SaveManager::loadGame(int slot) { delete saveFile; } -/** - * Save the game in the specified slot with the given name - */ void SaveManager::saveGame(int slot, const Common::String &name) { Common::OutSaveFile *out = g_system->getSavefileManager()->openForSaving( generateSaveName(slot)); @@ -354,17 +324,10 @@ void SaveManager::saveGame(int slot, const Common::String &name) { delete out; } -/** - * Support method that generates a savegame name - * @param slot Slot number - */ Common::String SaveManager::generateSaveName(int slot) { return Common::String::format("%s.%03d", _target.c_str(), slot); } -/** - * Synchronize the data for a savegame - */ void SaveManager::synchronize(Common::Serializer &s) { Inventory &inv = *_vm->_inventory; Journal &journal = *_vm->_journal; @@ -391,9 +354,6 @@ void SaveManager::synchronize(Common::Serializer &s) { _justLoaded = true; } -/** - * Make sure that the selected savegame is on-screen - */ bool SaveManager::checkGameOnScreen(int slot) { Screen &screen = *_vm->_screen; diff --git a/engines/sherlock/saveload.h b/engines/sherlock/saveload.h index c9a7286c6b..371a6e4c79 100644 --- a/engines/sherlock/saveload.h +++ b/engines/sherlock/saveload.h @@ -56,8 +56,14 @@ private: Common::String _target; Graphics::Surface *_saveThumb; + /** + * Build up a savegame list, with empty slots given an explicit Empty message + */ void createSavegameList(); + /** + * Synchronize the data for a savegame + */ void synchronize(Common::Serializer &s); public: Common::StringArray _savegames; @@ -68,27 +74,65 @@ public: SaveManager(SherlockEngine *vm, const Common::String &target); ~SaveManager(); + /** + * Shows the in-game dialog interface for loading and saving games + */ void drawInterface(); + /** + * Creates a thumbnail for the current on-screen contents + */ void createThumbnail(); + /** + * Load a list of savegames + */ static SaveStateList getSavegameList(const Common::String &target); + /** + * Support method that generates a savegame name + * @param slot Slot number + */ Common::String generateSaveName(int slot); + /** + * Write out the header information for a savegame + */ void writeSavegameHeader(Common::OutSaveFile *out, SherlockSavegameHeader &header); + /** + * Read in the header information for a savegame + */ static bool readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header); + /** + * Return the index of the button the mouse is over, if any + */ int getHighlightedButton() const; + /** + * Handle highlighting buttons + */ void highlightButtons(int btnIndex); + /** + * Load the game in the specified slot + */ void loadGame(int slot); + + /** + * Save the game in the specified slot with the given name + */ void saveGame(int slot, const Common::String &name); + /** + * Make sure that the selected savegame is on-screen + */ bool checkGameOnScreen(int slot); + /** + * Prompts the user to enter a filename in a given slot + */ bool getFilename(int slot); }; diff --git a/engines/sherlock/scalpel/darts.cpp b/engines/sherlock/scalpel/darts.cpp index 29b67216b9..e861b9cd62 100644 --- a/engines/sherlock/scalpel/darts.cpp +++ b/engines/sherlock/scalpel/darts.cpp @@ -64,9 +64,6 @@ Darts::Darts(ScalpelEngine *vm) : _vm(vm) { _oldDartButtons = false; } -/** - * Main method for playing darts game - */ void Darts::playDarts() { Events &events = *_vm->_events; Screen &screen = *_vm->_screen; @@ -182,9 +179,6 @@ void Darts::playDarts() { screen.setFont(oldFont); } -/** - * Load the graphics needed for the dart game - */ void Darts::loadDarts() { Screen &screen = *_vm->_screen; @@ -195,9 +189,6 @@ void Darts::loadDarts() { screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } -/** - * Initializes the variables needed for the dart game - */ void Darts::initDarts() { _dartScore1 = _dartScore2 = 301; _roundNumber = 1; @@ -220,17 +211,11 @@ void Darts::initDarts() { _opponent = OPPONENT_NAMES[_level]; } -/** - * Frees the images used by the dart game - */ void Darts::closeDarts() { delete _dartImages; _dartImages = nullptr; } -/** - * Show the names of the people playing, Holmes and his opponent - */ void Darts::showNames(int playerNum) { Screen &screen = *_vm->_screen; byte color = playerNum == 0 ? PLAYER_COLOR : DART_COL_FORE; @@ -263,9 +248,6 @@ void Darts::showNames(int playerNum) { screen._backBuffer2.blitFrom(screen._backBuffer1); } -/** - * Show the player score and game status - */ void Darts::showStatus(int playerNum) { Screen &screen = *_vm->_screen; byte color; @@ -284,12 +266,6 @@ void Darts::showStatus(int playerNum) { screen.slamRect(Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10, SHERLOCK_SCREEN_WIDTH, STATUS_INFO_Y + 48)); } -/** - * Throws a single dart. - * @param dartNum Dart number - * @param computer 0 = Player, 1 = 1st player computer, 2 = 2nd player computer - * @returns Score for what dart hit - */ int Darts::throwDart(int dartNum, int computer) { Events &events = *_vm->_events; Screen &screen = *_vm->_screen; @@ -348,9 +324,6 @@ int Darts::throwDart(int dartNum, int computer) { return dartScore(dartPos); } -/** - * Draw a dart moving towards the board - */ void Darts::drawDartThrow(const Common::Point &pt) { Events &events = *_vm->_events; Screen &screen = *_vm->_screen; @@ -390,9 +363,6 @@ void Darts::drawDartThrow(const Common::Point &pt) { screen.slamRect(oldDrawBounds); } -/** - * Erases the power bars - */ void Darts::erasePowerBars() { Screen &screen = *_vm->_screen; @@ -404,11 +374,6 @@ void Darts::erasePowerBars() { screen.slamArea(DARTBARVX - 1, DARTHEIGHTY - 1, 11, DARTBARSIZE + 3); } -/** - * Show a gradually incrementing incrementing power that bar. If goToPower is provided, it will - * increment to that power level ignoring all keyboard input (ie. for computer throws). - * Otherwise, it will increment until either a key/mouse button is pressed, or it reaches the end - */ int Darts::doPowerBar(const Common::Point &pt, byte color, int goToPower, bool isVertical) { Events &events = *_vm->_events; Screen &screen = *_vm->_screen; @@ -459,9 +424,6 @@ int Darts::doPowerBar(const Common::Point &pt, byte color, int goToPower, bool i return MIN(idx * 100 / DARTBARSIZE, 100); } -/** - * Returns true if a mouse button or key is pressed. - */ bool Darts::dartHit() { Events &events = *_vm->_events; @@ -481,9 +443,6 @@ bool Darts::dartHit() { return (events._pressed && !_oldDartButtons) ? 1 : 0; } -/** - * Return the score of the given location on the dart-board - */ int Darts::dartScore(const Common::Point &pt) { Common::Point pos(pt.x - 37, pt.y - 33); Graphics::Surface &scoreImg = (*_dartImages)[1]._frame; @@ -497,10 +456,6 @@ int Darts::dartScore(const Common::Point &pt) { return score; } -/** - * Calculates where a computer player is trying to throw their dart, and choose the actual - * point that was hit with some margin of error - */ Common::Point Darts::getComputerDartDest(int playerNum) { Common::Point target; int score = playerNum == 0 ? _dartScore1 : _dartScore2; @@ -556,9 +511,6 @@ Common::Point Darts::getComputerDartDest(int playerNum) { return target; } -/** - * Returns the center position for the area of the dartboard with a given number - */ bool Darts::findNumberOnBoard(int aim, Common::Point &pt) { ImageFrame &board = (*_dartImages)[1]; @@ -598,10 +550,6 @@ bool Darts::findNumberOnBoard(int aim, Common::Point &pt) { return done; } -/** - * Set a global flag to 0 or 1 depending on whether the passed flag is negative or positive. - * @remarks We don't use the global setFlags method because we don't want to check scene flags - */ void Darts::setFlagsForDarts(int flagNum) { _vm->_flags[ABS(flagNum)] = flagNum >= 0; } diff --git a/engines/sherlock/scalpel/darts.h b/engines/sherlock/scalpel/darts.h index a9624442e2..42990f8056 100644 --- a/engines/sherlock/scalpel/darts.h +++ b/engines/sherlock/scalpel/darts.h @@ -44,30 +44,88 @@ private: int _roundScore; bool _oldDartButtons; + /** + * Load the graphics needed for the dart game + */ void loadDarts(); + + /** + * Initializes the variables needed for the dart game + */ void initDarts(); + + /** + * Frees the images used by the dart game + */ void closeDarts(); + /** + * Show the names of the people playing, Holmes and his opponent + */ void showNames(int playerNum); + + /** + * Show the player score and game status + */ void showStatus(int playerNum); + /** + * Throws a single dart. + * @param dartNum Dart number + * @param computer 0 = Player, 1 = 1st player computer, 2 = 2nd player computer + * @returns Score for what dart hit + */ int throwDart(int dartNum, int computer); + + /** + * Draw a dart moving towards the board + */ void drawDartThrow(const Common::Point &pt); + /** + * Erases the power bars + */ void erasePowerBars(); + + /** + * Show a gradually incrementing incrementing power that bar. If goToPower is provided, it will + * increment to that power level ignoring all keyboard input (ie. for computer throws). + * Otherwise, it will increment until either a key/mouse button is pressed, or it reaches the end + */ int doPowerBar(const Common::Point &pt, byte color, int goToPower, bool isVertical); + /** + * Returns true if a mouse button or key is pressed. + */ bool dartHit(); + + /** + * Return the score of the given location on the dart-board + */ int dartScore(const Common::Point &pt); + /** + * Calculates where a computer player is trying to throw their dart, and choose the actual + * point that was hit with some margin of error + */ Common::Point getComputerDartDest(int playerNum); + /** + * Returns the center position for the area of the dartboard with a given number + */ bool findNumberOnBoard(int aim, Common::Point &pt); + /** + * Set a global flag to 0 or 1 depending on whether the passed flag is negative or positive. + * @remarks We don't use the global setFlags method because we don't want to check scene flags + */ void setFlagsForDarts(int flagNum); public: Darts(ScalpelEngine *vm); + /** + * Main method for playing darts game + */ void playDarts(); }; diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index e47be791f0..170768d91d 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -238,9 +238,6 @@ ScalpelEngine::~ScalpelEngine() { delete _darts; } -/** - * Game initialization - */ void ScalpelEngine::initialize() { SherlockEngine::initialize(); @@ -276,9 +273,6 @@ void ScalpelEngine::initialize() { _scene->_goToScene = 4; } -/** - * Show the opening sequence - */ void ScalpelEngine::showOpening() { if (isDemo() && _interactiveFl) return; @@ -296,9 +290,6 @@ void ScalpelEngine::showOpening() { _sound->stopMusic(); } -/** - * Show the starting city cutscene which shows the game title - */ bool ScalpelEngine::showCityCutscene() { byte palette[PALETTE_SIZE]; @@ -371,9 +362,6 @@ bool ScalpelEngine::showCityCutscene() { return finished; } -/** - * Show the back alley where the initial murder takes place - */ bool ScalpelEngine::showAlleyCutscene() { byte palette[PALETTE_SIZE]; _sound->playMusic("prolog2.mus"); @@ -411,9 +399,6 @@ bool ScalpelEngine::showAlleyCutscene() { return finished; } -/** - * Show the Baker Street outside cutscene - */ bool ScalpelEngine::showStreetCutscene() { _animation->_gfxLibraryFilename = "TITLE.LIB"; _animation->_soundLibraryFilename = "TITLE.SND"; @@ -430,9 +415,7 @@ bool ScalpelEngine::showStreetCutscene() { return finished; } -/** - * Show the game credits - */ + bool ScalpelEngine::scrollCredits() { // Load the images for displaying credit text Common::SeekableReadStream *stream = _res->load("credits.vgs", "title.lib"); @@ -465,9 +448,6 @@ bool ScalpelEngine::scrollCredits() { return true; } -/** - * Show Holmes and Watson at the breakfast table, lestrade's note, and then the scrolling credits - */ bool ScalpelEngine::showOfficeCutscene() { _sound->playMusic("PROLOG4.MUS"); _animation->_gfxLibraryFilename = "TITLE2.LIB"; @@ -511,11 +491,6 @@ bool ScalpelEngine::showOfficeCutscene() { return finished; } -/** - * Load the default inventory for the game, which includes both the initial active inventory, - * as well as special pending inventory items which can appear automatically in the player's - * inventory once given required flags are set - */ void ScalpelEngine::loadInventory() { Inventory &inv = *_inventory; @@ -537,9 +512,6 @@ void ScalpelEngine::loadInventory() { inv.push_back(InventoryItem(586, "Pawn ticket", "A pawn ticket", "_ITEM16A")); } -/** - * Transition to show an image - */ void ScalpelEngine::showLBV(const Common::String &filename) { Common::SeekableReadStream *stream = _res->load(filename, "title.lib"); ImageFile images(*stream); @@ -550,9 +522,6 @@ void ScalpelEngine::showLBV(const Common::String &filename) { _screen->verticalTransition(); } -/** - * Starting a scene within the game - */ void ScalpelEngine::startScene() { if (_scene->_goToScene == OVERHEAD_MAP || _scene->_goToScene == OVERHEAD_MAP2) { // Show the map @@ -709,9 +678,6 @@ void ScalpelEngine::startScene() { _mapResult = _scene->_goToScene; } -/** - * Takes care of clearing the mirror in scene 12 (mansion drawing room), in case anything drew over it - */ void ScalpelEngine::eraseMirror12() { Common::Point pt((*_people)[AL]._position.x / 100, (*_people)[AL]._position.y / 100); @@ -722,9 +688,6 @@ void ScalpelEngine::eraseMirror12() { } } -/** - * Takes care of drawing Holme's reflection onto the mirror in scene 12 (mansion drawing room) - */ void ScalpelEngine::doMirror12() { People &people = *_people; Common::Point pt((*_people)[AL]._position.x / 100, (*_people)[AL]._position.y / 100); @@ -798,9 +761,6 @@ void ScalpelEngine::doMirror12() { } } -/** - * This clears the mirror in scene 12 (mansion drawing room) in case anything messed draw over it - */ void ScalpelEngine::flushMirror12() { Common::Point pt((*_people)[AL]._position.x / 100, (*_people)[AL]._position.y / 100); diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h index 62875f1e90..14e30ff996 100644 --- a/engines/sherlock/scalpel/scalpel.h +++ b/engines/sherlock/scalpel/scalpel.h @@ -39,27 +39,74 @@ private: Darts *_darts; int _mapResult; + /** + * Show the starting city cutscene which shows the game title + */ bool showCityCutscene(); + + /** + * Show the back alley where the initial murder takes place + */ bool showAlleyCutscene(); + + /** + * Show the Baker Street outside cutscene + */ bool showStreetCutscene(); + + /** + * Show Holmes and Watson at the breakfast table, lestrade's note, and then the scrolling credits + */ bool showOfficeCutscene(); + + /** + * Show the game credits + */ bool scrollCredits(); + /** + * Load the default inventory for the game, which includes both the initial active inventory, + * as well as special pending inventory items which can appear automatically in the player's + * inventory once given required flags are set + */ void loadInventory(); + /** + * Transition to show an image + */ void showLBV(const Common::String &filename); protected: + /** + * Game initialization + */ virtual void initialize(); + /** + * Show the opening sequence + */ virtual void showOpening(); + /** + * Starting a scene within the game + */ virtual void startScene(); public: ScalpelEngine(OSystem *syst, const SherlockGameDescription *gameDesc); virtual ~ScalpelEngine(); + /** + * Takes care of clearing the mirror in scene 12 (mansion drawing room), in case anything drew over it + */ void eraseMirror12(); + + /** + * Takes care of drawing Holme's reflection onto the mirror in scene 12 (mansion drawing room) + */ void doMirror12(); + + /** + * This clears the mirror in scene 12 (mansion drawing room) in case anything messed draw over it + */ void flushMirror12(); }; diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index e71bc7eef7..5ac43fc1be 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -33,9 +33,6 @@ static const int FS_TRANS[8] = { /*----------------------------------------------------------------*/ -/** - * Load the data for the object - */ void BgFileHeader::load(Common::SeekableReadStream &s) { _numStructs = s.readUint16LE(); _numImages = s.readUint16LE(); @@ -47,9 +44,6 @@ void BgFileHeader::load(Common::SeekableReadStream &s) { /*----------------------------------------------------------------*/ -/** - * Load the data for the object - */ void BgFileHeaderInfo::load(Common::SeekableReadStream &s) { _filesize = s.readUint32LE(); _maxFrames = s.readByte(); @@ -61,9 +55,6 @@ void BgFileHeaderInfo::load(Common::SeekableReadStream &s) { /*----------------------------------------------------------------*/ -/** - * Load the data for the object - */ void Exit::load(Common::SeekableReadStream &s) { int xp = s.readSint16LE(); int yp = s.readSint16LE(); @@ -80,9 +71,6 @@ void Exit::load(Common::SeekableReadStream &s) { /*----------------------------------------------------------------*/ -/** - * Load the data for the object - */ void SceneEntry::load(Common::SeekableReadStream &s) { _startPosition.x = s.readSint16LE(); _startPosition.y = s.readSint16LE(); @@ -90,9 +78,6 @@ void SceneEntry::load(Common::SeekableReadStream &s) { _allow = s.readByte(); } -/** - * Load the data for the object - */ void SceneSound::load(Common::SeekableReadStream &s) { char buffer[9]; s.read(buffer, 8); @@ -104,9 +89,6 @@ void SceneSound::load(Common::SeekableReadStream &s) { /*----------------------------------------------------------------*/ -/** - * Retuurn the index of the passed object in the array - */ int ObjectArray::indexOf(const Object &obj) const { for (uint idx = 0; idx < size(); ++idx) { if (&(*this)[idx] == &obj) @@ -143,9 +125,6 @@ Scene::~Scene() { freeScene(); } -/** - * Handles loading the scene specified by _goToScene - */ void Scene::selectScene() { Events &events = *_vm->_events; People &people = *_vm->_people; @@ -189,9 +168,6 @@ void Scene::selectScene() { talk._scriptMoreFlag = 0; } -/** - * Fres all the graphics and other dynamically allocated data for the scene - */ void Scene::freeScene() { if (_currentScene == -1) return; @@ -221,15 +197,6 @@ void Scene::freeScene() { _currentScene = -1; } -/** - * Loads the data associated for a given scene. The .BGD file's format is: - * BGHEADER: Holds an index for the rest of the file - * STRUCTS: The objects for the scene - * IMAGES: The graphic information for the structures - * - * The _misc field of the structures contains the number of the graphic image - * that it should point to after loading; _misc is then set to 0. - */ bool Scene::loadScene(const Common::String &filename) { Events &events = *_vm->_events; Map &map = *_vm->_map; @@ -513,10 +480,6 @@ bool Scene::loadScene(const Common::String &filename) { return flag; } -/** - * Set objects to their current persistent state. This includes things such as - * opening or moving them - */ void Scene::checkSceneStatus() { if (_sceneStats[_currentScene][64]) { for (uint idx = 0; idx < 64; ++idx) { @@ -542,10 +505,6 @@ void Scene::checkSceneStatus() { } } -/** - * Restores objects to the correct status. This ensures that things like being opened or moved - * will remain the same on future visits to the scene - */ void Scene::saveSceneStatus() { // Flag any objects for the scene that have been altered int count = MIN((int)_bgShapes.size(), 64); @@ -559,11 +518,6 @@ void Scene::saveSceneStatus() { _sceneStats[_currentScene][64] = true; } -/** - * Check the scene's objects against the game flags. If false is passed, - * it means the scene has just been loaded. A value of true means that the scene - * is in use (ie. not just loaded) - */ void Scene::checkSceneFlags(bool flag) { SpriteType mode = flag ? HIDE_SHAPE : HIDDEN; @@ -616,11 +570,6 @@ void Scene::checkSceneFlags(bool flag) { } } -/** - * Checks scene objects against the player's inventory items. If there are any - * matching names, it means the given item has already been picked up, and should - * be hidden in the scene. - */ void Scene::checkInventory() { for (uint shapeIdx = 0; shapeIdx < _bgShapes.size(); ++shapeIdx) { for (int invIdx = 0; invIdx < _vm->_inventory->_holdings; ++invIdx) { @@ -632,10 +581,6 @@ void Scene::checkInventory() { } } -/** - * Set up any entrance co-ordinates or entrance canimations, and then transition - * in the scene - */ void Scene::transitionToScene() { People &people = *_vm->_people; SaveManager &saves = *_vm->_saves; @@ -750,10 +695,6 @@ void Scene::transitionToScene() { } } -/** - * Scans through the object list to find one with a matching name, and will - * call toggleHidden with all matches found. Returns the numer of matches found - */ int Scene::toggleObject(const Common::String &name) { int count = 0; @@ -767,10 +708,6 @@ int Scene::toggleObject(const Common::String &name) { return count; } -/** - * Update the screen back buffer with all of the scene objects which need - * to be drawn - */ void Scene::updateBackground() { People &people = *_vm->_people; Screen &screen = *_vm->_screen; @@ -860,9 +797,6 @@ void Scene::updateBackground() { screen.resetDisplayBounds(); } -/** - * Check whether the passed area intersects with one of the scene's exits - */ Exit *Scene::checkForExit(const Common::Rect &r) { for (uint idx = 0; idx < _exits.size(); ++idx) { if (_exits[idx]._bounds.intersects(r)) @@ -872,11 +806,6 @@ Exit *Scene::checkForExit(const Common::Rect &r) { return nullptr; } -/** - * Checks all the background shapes. If a background shape is animating, - * it will flag it as needing to be drawn. If a non-animating shape is - * colliding with another shape, it will also flag it as needing drawing - */ void Scene::checkBgShapes(ImageFrame *frame, const Common::Point &pt) { // Iterate through the shapes for (uint idx = 0; idx < _bgShapes.size(); ++idx) { @@ -911,14 +840,6 @@ void Scene::checkBgShapes(ImageFrame *frame, const Common::Point &pt) { } } -/** - * Attempt to start a canimation sequence. It will load the requisite graphics, and - * then copy the canim object into the _canimShapes array to start the animation. - * - * @param cAnimNum The canim object within the current scene - * @param playRate Play rate. 0 is invalid; 1=normal speed, 2=1/2 speed, etc. - * A negative playRate can also be specified to play the animation in reverse - */ int Scene::startCAnim(int cAnimNum, int playRate) { Events &events = *_vm->_events; Map &map = *_vm->_map; @@ -1131,9 +1052,6 @@ int Scene::startCAnim(int cAnimNum, int playRate) { return 1; } -/** - * Animate all objects and people. - */ void Scene::doBgAnim() { Events &events = *_vm->_events; Inventory &inv = *_vm->_inventory; @@ -1461,10 +1379,6 @@ void Scene::doBgAnim() { } } -/** - * Attempts to find a background shape within the passed bounds. If found, - * it will return the shape number, or -1 on failure. - */ int Scene::findBgShape(const Common::Rect &r) { if (!_doBgAnimDone) // New frame hasn't been drawn yet @@ -1485,10 +1399,6 @@ int Scene::findBgShape(const Common::Rect &r) { return -1; } -/** - * Checks to see if the given position in the scene belongs to a given zone type. - * If it is, the zone is activated and used just like a TAKL zone or aFLAG_SET zone. - */ int Scene::checkForZones(const Common::Point &pt, int zoneType) { int matches = 0; @@ -1508,9 +1418,6 @@ int Scene::checkForZones(const Common::Point &pt, int zoneType) { return matches; } -/** - * Check which zone the the given position is located in. - */ int Scene::whichZone(const Common::Point &pt) { for (uint idx = 0; idx < _zones.size(); ++idx) { if (_zones[idx].contains(pt)) @@ -1520,9 +1427,6 @@ int Scene::whichZone(const Common::Point &pt) { return -1; } -/** - * Returns the index of the closest zone to a given point. - */ int Scene::closestZone(const Common::Point &pt) { int dist = 1000; int zone = -1; @@ -1542,9 +1446,6 @@ int Scene::closestZone(const Common::Point &pt) { return zone; } -/** - * Synchronize the data for a savegame - */ void Scene::synchronize(Common::Serializer &s) { if (s.isSaving()) saveSceneStatus(); diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 78d41299e6..243aba20f8 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -46,6 +46,9 @@ struct BgFileHeader { int _seqSize; int _fill; + /** + * Load the data for the object + */ void load(Common::SeekableReadStream &s); }; @@ -54,6 +57,9 @@ struct BgFileHeaderInfo { int _maxFrames; // How many unique frames in object Common::String _filename; // Filename of object + /** + * Load the data for the object + */ void load(Common::SeekableReadStream &s); }; @@ -65,6 +71,9 @@ struct Exit { Common::Point _people; int _peopleDir; + /** + * Load the data for the object + */ void load(Common::SeekableReadStream &s); }; @@ -73,6 +82,9 @@ struct SceneEntry { int _startDir; int _allow; + /** + * Load the data for the object + */ void load(Common::SeekableReadStream &s); }; @@ -80,11 +92,17 @@ struct SceneSound { Common::String _name; int _priority; + /** + * Load the data for the object + */ void load(Common::SeekableReadStream &s); }; class ObjectArray : public Common::Array { public: + /** + * Retuurn the index of the passed object in the array + */ int indexOf(const Object &obj) const; }; @@ -96,16 +114,47 @@ private: bool _lookHelp; bool _loadingSavedGame; + /** + * Loads the data associated for a given scene. The .BGD file's format is: + * BGHEADER: Holds an index for the rest of the file + * STRUCTS: The objects for the scene + * IMAGES: The graphic information for the structures + * + * The _misc field of the structures contains the number of the graphic image + * that it should point to after loading; _misc is then set to 0. + */ bool loadScene(const Common::String &filename); + /** + * Set objects to their current persistent state. This includes things such as + * opening or moving them + */ void checkSceneStatus(); + /** + * Checks scene objects against the player's inventory items. If there are any + * matching names, it means the given item has already been picked up, and should + * be hidden in the scene. + */ void checkInventory(); + /** + * Set up any entrance co-ordinates or entrance canimations, and then transition + * in the scene + */ void transitionToScene(); + /** + * Checks all the background shapes. If a background shape is animating, + * it will flag it as needing to be drawn. If a non-animating shape is + * colliding with another shape, it will also flag it as needing drawing + */ void checkBgShapes(ImageFrame *frame, const Common::Point &pt); + /** + * Restores objects to the correct status. This ensures that things like being opened or moved + * will remain the same on future visits to the scene + */ void saveSceneStatus(); public: int _currentScene; @@ -143,32 +192,80 @@ public: Scene(SherlockEngine *vm); ~Scene(); + /** + * Handles loading the scene specified by _goToScene + */ void selectScene(); + /** + * Fres all the graphics and other dynamically allocated data for the scene + */ void freeScene(); + /** + * Check the scene's objects against the game flags. If false is passed, + * it means the scene has just been loaded. A value of true means that the scene + * is in use (ie. not just loaded) + */ void checkSceneFlags(bool mode); + /** + * Check whether the passed area intersects with one of the scene's exits + */ Exit *checkForExit(const Common::Rect &r); + /** + * Attempt to start a canimation sequence. It will load the requisite graphics, and + * then copy the canim object into the _canimShapes array to start the animation. + * + * @param cAnimNum The canim object within the current scene + * @param playRate Play rate. 0 is invalid; 1=normal speed, 2=1/2 speed, etc. + * A negative playRate can also be specified to play the animation in reverse + */ int startCAnim(int cAnimNum, int playRate); + /** + * Scans through the object list to find one with a matching name, and will + * call toggleHidden with all matches found. Returns the numer of matches found + */ int toggleObject(const Common::String &name); + /** + * Animate all objects and people. + */ void doBgAnim(); - void clearInfo(); - + /** + * Attempts to find a background shape within the passed bounds. If found, + * it will return the shape number, or -1 on failure. + */ int findBgShape(const Common::Rect &r); + /** + * Checks to see if the given position in the scene belongs to a given zone type. + * If it is, the zone is activated and used just like a TAKL zone or aFLAG_SET zone. + */ int checkForZones(const Common::Point &pt, int zoneType); + /** + * Check which zone the the given position is located in. + */ int whichZone(const Common::Point &pt); + /** + * Returns the index of the closest zone to a given point. + */ int closestZone(const Common::Point &pt); + /** + * Update the screen back buffer with all of the scene objects which need + * to be drawn + */ void updateBackground(); + /** + * Synchronize the data for a savegame + */ void synchronize(Common::Serializer &s); }; diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index f43bf17288..583ac5b485 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -49,9 +49,6 @@ Screen::~Screen() { delete _font; } -/** - * Set the font to use for writing text on the screen - */ void Screen::setFont(int fontNumb) { // Interactive demo doesn't use fonts if (!_vm->_interactiveFl) @@ -70,9 +67,6 @@ void Screen::setFont(int fontNumb) { _fontHeight = MAX((uint16)_fontHeight, (*_font)[idx]._frame.h); } -/** - * Handles updating any dirty areas of the screen Surface object to the physical screen - */ void Screen::update() { // Merge the dirty rects mergeDirtyRects(); @@ -91,23 +85,14 @@ void Screen::update() { _dirtyRects.clear(); } -/** - * Return the currently active palette - */ void Screen::getPalette(byte palette[PALETTE_SIZE]) { g_system->getPaletteManager()->grabPalette(palette, 0, PALETTE_COUNT); } -/** - * Set the palette - */ void Screen::setPalette(const byte palette[PALETTE_SIZE]) { g_system->getPaletteManager()->setPalette(palette, 0, PALETTE_COUNT); } -/** - * Fades from the currently active palette to the passed palette - */ int Screen::equalizePalette(const byte palette[PALETTE_SIZE]) { int total = 0; byte tempPalette[PALETTE_SIZE]; @@ -132,9 +117,6 @@ int Screen::equalizePalette(const byte palette[PALETTE_SIZE]) { return total; } -/** - * Fade out the palette to black - */ void Screen::fadeToBlack(int speed) { byte tempPalette[PALETTE_SIZE]; Common::fill(&tempPalette[0], &tempPalette[PALETTE_SIZE], 0); @@ -147,9 +129,6 @@ void Screen::fadeToBlack(int speed) { fillRect(Common::Rect(0, 0, this->w, this->h), 0); } -/** - * Fade in a given palette - */ void Screen::fadeIn(const byte palette[PALETTE_SIZE], int speed) { int count = 50; while (equalizePalette(palette) && --count) { @@ -159,18 +138,11 @@ void Screen::fadeIn(const byte palette[PALETTE_SIZE], int speed) { setPalette(palette); } -/** - * Adds a rectangle to the list of modified areas of the screen during the - * current frame - */ void Screen::addDirtyRect(const Common::Rect &r) { _dirtyRects.push_back(r); assert(r.width() > 0 && r.height() > 0); } -/** - * Merges together overlapping dirty areas of the screen - */ void Screen::mergeDirtyRects() { Common::List::iterator rOuter, rInner; @@ -195,9 +167,6 @@ void Screen::mergeDirtyRects() { } } -/** - * Returns the union of two dirty area rectangles - */ bool Screen::unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2) { destRect = src1; destRect.extend(src2); @@ -205,9 +174,6 @@ bool Screen::unionRectangle(Common::Rect &destRect, const Common::Rect &src1, co return !destRect.isEmpty(); } -/** - * Do a random pixel transition in from _backBuffer surface to the screen - */ void Screen::randomTransition() { Events &events = *_vm->_events; const int TRANSITION_MULTIPLIER = 0x15a4e35; @@ -234,9 +200,6 @@ void Screen::randomTransition() { blitFrom(*_backBuffer); } -/** - * Transition to the surface from _backBuffer using a vertical transition - */ void Screen::verticalTransition() { Events &events = *_vm->_events; @@ -259,9 +222,6 @@ void Screen::verticalTransition() { } } -/** - * Copies a section of the second back buffer into the main back buffer - */ void Screen::restoreBackground(const Common::Rect &r) { if (r.width() > 0 && r.height() > 0) { Common::Rect tempRect = r; @@ -272,16 +232,10 @@ void Screen::restoreBackground(const Common::Rect &r) { } } -/** - * Copies a given area to the screen - */ void Screen::slamArea(int16 xp, int16 yp, int16 width, int16 height) { slamRect(Common::Rect(xp, yp, xp + width, yp + height)); } -/** - * Copies a given area to the screen - */ void Screen::slamRect(const Common::Rect &r) { if (r.width() && r.height() > 0) { Common::Rect tempRect = r; @@ -292,10 +246,6 @@ void Screen::slamRect(const Common::Rect &r) { } } -/** - * Copy an image from the back buffer to the screen, taking care of both the - * new area covered by the shape as well as the old area, which must be restored - */ void Screen::flushImage(ImageFrame *frame, const Common::Point &pt, int16 *xp, int16 *yp, int16 *width, int16 *height) { Common::Point imgPos = pt + frame->_offset; @@ -322,10 +272,6 @@ void Screen::flushImage(ImageFrame *frame, const Common::Point &pt, *height = newBounds.height(); } -/** - * Prints the text passed onto the back buffer at the given position and color. - * The string is then blitted to the screen - */ void Screen::print(const Common::Point &pt, byte color, const char *formatStr, ...) { // Create the string to display va_list args; @@ -354,9 +300,6 @@ void Screen::print(const Common::Point &pt, byte color, const char *formatStr, . slamRect(textBounds); } -/** - * Print a strings onto the back buffer without blitting it to the screen - */ void Screen::gPrint(const Common::Point &pt, byte color, const char *formatStr, ...) { // Create the string to display va_list args; @@ -368,10 +311,6 @@ void Screen::gPrint(const Common::Point &pt, byte color, const char *formatStr, writeString(str, pt, color); } - -/** - * Returns the width of a string in pixels - */ int Screen::stringWidth(const Common::String &str) { int width = 0; @@ -381,9 +320,6 @@ int Screen::stringWidth(const Common::String &str) { return width; } -/** - * Returns the width of a character in pixels - */ int Screen::charWidth(char c) { if (c == ' ') return 5; @@ -393,9 +329,6 @@ int Screen::charWidth(char c) { return 0; } -/** - * Draws the given string into the back buffer using the images stored in _font - */ void Screen::writeString(const Common::String &str, const Common::Point &pt, byte color) { Common::Point charPos = pt; @@ -411,17 +344,11 @@ void Screen::writeString(const Common::String &str, const Common::Point &pt, byt } } -/** - * Fills an area on the back buffer, and then copies it to the screen - */ void Screen::vgaBar(const Common::Rect &r, int color) { _backBuffer->fillRect(r, color); slamRect(r); } -/** - * Draws a button for use in the inventory, talk, and examine dialogs. - */ void Screen::makeButton(const Common::Rect &bounds, int textX, const Common::String &str) { @@ -437,10 +364,6 @@ void Screen::makeButton(const Common::Rect &bounds, int textX, COMMAND_FOREGROUND, "%s", str.c_str() + 1); } -/** - * Prints an interface command with the first letter highlighted to indicate - * what keyboard shortcut is associated with it - */ void Screen::buttonPrint(const Common::Point &pt, byte color, bool slamIt, const Common::String &str) { int xStart = pt.x - stringWidth(str) / 2; @@ -463,9 +386,6 @@ void Screen::buttonPrint(const Common::Point &pt, byte color, bool slamIt, } } -/** - * Draw a panel in the back buffer with a raised area effect around the edges - */ void Screen::makePanel(const Common::Rect &r) { _backBuffer->fillRect(r, BUTTON_MIDDLE); _backBuffer->hLine(r.left, r.top, r.right - 2, BUTTON_TOP); @@ -479,10 +399,6 @@ void Screen::makePanel(const Common::Rect &r) { _backBuffer->hLine(r.left + 1, r.bottom - 2, r.right - 1, BUTTON_BOTTOM); } -/** - * Draw a field in the back buffer with a raised area effect around the edges, - * suitable for text input. - */ void Screen::makeField(const Common::Rect &r) { _backBuffer->fillRect(r, BUTTON_MIDDLE); _backBuffer->hLine(r.left, r.top, r.right - 1, BUTTON_BOTTOM); @@ -491,9 +407,6 @@ void Screen::makeField(const Common::Rect &r) { _backBuffer->vLine(r.right - 1, r.top + 1, r.bottom - 2, BUTTON_TOP); } -/** - * Sets the active back buffer pointer to a restricted sub-area of the first back buffer - */ void Screen::setDisplayBounds(const Common::Rect &r) { assert(r.left == 0 && r.top == 0); _sceneSurface.setPixels(_backBuffer1.getPixels()); @@ -503,24 +416,15 @@ void Screen::setDisplayBounds(const Common::Rect &r) { _backBuffer = &_sceneSurface; } -/** - * Resets the active buffer pointer to point back to the full first back buffer - */ void Screen::resetDisplayBounds() { _backBuffer = &_backBuffer1; } -/** - * Return the size of the current display window - */ Common::Rect Screen::getDisplayBounds() { return (_backBuffer == &_sceneSurface) ? Common::Rect(0, 0, _sceneSurface.w, _sceneSurface.h) : Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } -/** - * Synchronize the data for a savegame - */ void Screen::synchronize(Common::Serializer &s) { int fontNumb = _fontNumber; s.syncAsByte(fontNumb); diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 2103588fe0..0369422bc3 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -66,12 +66,25 @@ private: int _fontHeight; Surface _sceneSurface; + /** + * Merges together overlapping dirty areas of the screen + */ void mergeDirtyRects(); + /** + * Returns the union of two dirty area rectangles + */ bool unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2); + /** + * Draws the given string into the back buffer using the images stored in _font + */ void writeString(const Common::String &str, const Common::Point &pt, byte color); protected: + /** + * Adds a rectangle to the list of modified areas of the screen during the + * current frame + */ virtual void addDirtyRect(const Common::Rect &r); public: Surface _backBuffer1, _backBuffer2; @@ -83,54 +96,141 @@ public: Screen(SherlockEngine *vm); virtual ~Screen(); + /** + * Set the font to use for writing text on the screen + */ void setFont(int fontNumber); + /** + * Handles updating any dirty areas of the screen Surface object to the physical screen + */ void update(); + /** + * Return the currently active palette + */ void getPalette(byte palette[PALETTE_SIZE]); + /** + * Set the palette + */ void setPalette(const byte palette[PALETTE_SIZE]); + /** + * Fades from the currently active palette to the passed palette + */ int equalizePalette(const byte palette[PALETTE_SIZE]); + /** + * Fade out the palette to black + */ void fadeToBlack(int speed = 2); + /** + * Fade in a given palette + */ void fadeIn(const byte palette[PALETTE_SIZE], int speed = 2); + /** + * Do a random pixel transition in from _backBuffer surface to the screen + */ void randomTransition(); + /** + * Transition to the surface from _backBuffer using a vertical transition + */ void verticalTransition(); + /** + * Prints the text passed onto the back buffer at the given position and color. + * The string is then blitted to the screen + */ void print(const Common::Point &pt, byte color, const char *formatStr, ...); + + /** + * Print a strings onto the back buffer without blitting it to the screen + */ void gPrint(const Common::Point &pt, byte color, const char *formatStr, ...); + /** + * Copies a section of the second back buffer into the main back buffer + */ void restoreBackground(const Common::Rect &r); + /** + * Copies a given area to the screen + */ void slamArea(int16 xp, int16 yp, int16 width, int16 height); + + /** + * Copies a given area to the screen + */ void slamRect(const Common::Rect &r); + /** + * Copy an image from the back buffer to the screen, taking care of both the + * new area covered by the shape as well as the old area, which must be restored + */ void flushImage(ImageFrame *frame, const Common::Point &pt, int16 *xp, int16 *yp, int16 *width, int16 *height); + /** + * Returns the width of a string in pixels + */ int stringWidth(const Common::String &str); + /** + * Returns the width of a character in pixels + */ int charWidth(char c); + /** + * Fills an area on the back buffer, and then copies it to the screen + */ void vgaBar(const Common::Rect &r, int color); + /** + * Draws a button for use in the inventory, talk, and examine dialogs. + */ void makeButton(const Common::Rect &bounds, int textX, const Common::String &str); + /** + * Prints an interface command with the first letter highlighted to indicate + * what keyboard shortcut is associated with it + */ void buttonPrint(const Common::Point &pt, byte color, bool slamIt, const Common::String &str); + /** + * Draw a panel in the back buffer with a raised area effect around the edges + */ void makePanel(const Common::Rect &r); + + /** + * Draw a field in the back buffer with a raised area effect around the edges, + * suitable for text input. + */ void makeField(const Common::Rect &r); + /** + * Sets the active back buffer pointer to a restricted sub-area of the first back buffer + */ void setDisplayBounds(const Common::Rect &r); + + /** + * Resets the active buffer pointer to point back to the full first back buffer + */ void resetDisplayBounds(); + + /** + * Return the size of the current display window + */ Common::Rect getDisplayBounds(); int fontNumber() const { return _fontNumber; } + /** + * Synchronize the data for a savegame + */ void synchronize(Common::Serializer &s); }; diff --git a/engines/sherlock/settings.cpp b/engines/sherlock/settings.cpp index 036177adbe..9f1549a0b8 100644 --- a/engines/sherlock/settings.cpp +++ b/engines/sherlock/settings.cpp @@ -52,9 +52,6 @@ static const char *const SETUP_NAMES[12] = { /*----------------------------------------------------------------*/ -/** - * Draws the interface for the settings window - */ void Settings::drawInteface(bool flag) { People &people = *_vm->_people; Screen &screen = *_vm->_screen; @@ -135,9 +132,6 @@ void Settings::drawInteface(bool flag) { } } -/** - * Draws the buttons for the settings dialog - */ int Settings::drawButtons(const Common::Point &pt, int _key) { Events &events = *_vm->_events; People &people = *_vm->_people; @@ -209,13 +203,6 @@ int Settings::drawButtons(const Common::Point &pt, int _key) { return found; } - -/** -* Handles input when the settings window is being shown -* @remarks Whilst this would in theory be better in the Journal class, since it displays in -* the user interface, it uses so many internal UI fields, that it sort of made some sense -* to put it in the UserInterface class. -*/ void Settings::show(SherlockEngine *vm) { Events &events = *vm->_events; People &people = *vm->_people; diff --git a/engines/sherlock/settings.h b/engines/sherlock/settings.h index 25d27d48df..fc5fb2959f 100644 --- a/engines/sherlock/settings.h +++ b/engines/sherlock/settings.h @@ -36,10 +36,22 @@ private: Settings(SherlockEngine *vm) : _vm(vm) {} + /** + * Draws the interface for the settings window + */ void drawInteface(bool flag); + /** + * Draws the buttons for the settings dialog + */ int drawButtons(const Common::Point &pt, int key); public: + /** + * Handles input when the settings window is being shown + * @remarks Whilst this would in theory be better in the Journal class, since it displays in + * the user interface, it uses so many internal UI fields, that it sort of made some sense + * to put it in the UserInterface class. + */ static void show(SherlockEngine *vm); }; diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index fd5c9a84d5..d4644d4d9d 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -69,9 +69,6 @@ SherlockEngine::~SherlockEngine() { delete _res; } -/** - * Does basic initialization of the game engine - */ void SherlockEngine::initialize() { initGraphics(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT, false); @@ -108,9 +105,6 @@ void SherlockEngine::initialize() { loadConfig(); } -/** - * Main method for running the game - */ Common::Error SherlockEngine::run() { // Initialize the engine initialize(); @@ -160,9 +154,6 @@ Common::Error SherlockEngine::run() { return Common::kNoError; } -/** - * Main loop for displaying a scene and handling all that occurs within it - */ void SherlockEngine::sceneLoop() { while (!shouldQuit() && _scene->_goToScene == -1) { // See if a script needs to be completed from either a goto room code, @@ -187,9 +178,6 @@ void SherlockEngine::sceneLoop() { } -/** - * Handle all player input - */ void SherlockEngine::handleInput() { _canLoadSave = true; _events->pollEventsAndWait(); @@ -201,11 +189,6 @@ void SherlockEngine::handleInput() { _ui->handleInput(); } -/** - * Read the state of a global flag - * @remarks If a negative value is specified, it will return the inverse value - * of the positive flag number - */ bool SherlockEngine::readFlags(int flagNum) { bool value = _flags[ABS(flagNum)]; if (flagNum < 0) @@ -214,19 +197,12 @@ bool SherlockEngine::readFlags(int flagNum) { return value; } -/** - * Sets a global flag to either true or false depending on whether the specified - * flag is positive or negative - */ void SherlockEngine::setFlags(int flagNum) { _flags[ABS(flagNum)] = flagNum >= 0; _scene->checkSceneFlags(true); } -/** - * Load game configuration esttings - */ void SherlockEngine::loadConfig() { // Load sound settings syncSoundSettings(); @@ -240,9 +216,6 @@ void SherlockEngine::loadConfig() { _people->_portraitsOn = ConfMan.getBool("portraits_on"); } -/** - * Saves game configuration information - */ void SherlockEngine::saveConfig() { ConfMan.setBool("mute", !_sound->_digitized); ConfMan.setBool("music_mute", !_sound->_music); @@ -257,9 +230,6 @@ void SherlockEngine::saveConfig() { ConfMan.flushToDisk(); } -/** - * Called by the engine when sound settings are updated - */ void SherlockEngine::syncSoundSettings() { Engine::syncSoundSettings(); @@ -267,39 +237,24 @@ void SherlockEngine::syncSoundSettings() { _sound->syncSoundSettings(); } -/** - * Synchronize the data for a savegame - */ void SherlockEngine::synchronize(Common::Serializer &s) { for (uint idx = 0; idx < _flags.size(); ++idx) s.syncAsByte(_flags[idx]); } -/** - * Returns true if a savegame can be loaded - */ bool SherlockEngine::canLoadGameStateCurrently() { return _canLoadSave; } -/** - * Returns true if the game can be saved - */ bool SherlockEngine::canSaveGameStateCurrently() { return _canLoadSave; } -/** - * Called by the GMM to load a savegame - */ Common::Error SherlockEngine::loadGameState(int slot) { _saves->loadGame(slot); return Common::kNoError; } -/** - * Called by the GMM to save the game - */ Common::Error SherlockEngine::saveGameState(int slot, const Common::String &desc) { _saves->saveGame(slot, desc); return Common::kNoError; diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 830a255f5f..24a72076ef 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -68,18 +68,33 @@ class Resource; class SherlockEngine : public Engine { private: + /** + * Main loop for displaying a scene and handling all that occurs within it + */ void sceneLoop(); + /** + * Handle all player input + */ void handleInput(); + /** + * Load game configuration esttings + */ void loadConfig(); protected: + /** + * Does basic initialization of the game engine + */ virtual void initialize(); virtual void showOpening() = 0; virtual void startScene() {} + /** + * Returns a list of features the game itself supports + */ virtual bool hasFeature(EngineFeature f) const; public: const SherlockGameDescription *_gameDescription; @@ -108,29 +123,77 @@ public: SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc); virtual ~SherlockEngine(); + /** + * Main method for running the game + */ virtual Common::Error run(); + /** + * Returns true if a savegame can be loaded + */ virtual bool canLoadGameStateCurrently(); + + /** + * Returns true if the game can be saved + */ virtual bool canSaveGameStateCurrently(); + + /** + * Called by the GMM to load a savegame + */ virtual Common::Error loadGameState(int slot); + + /** + * Called by the GMM to save the game + */ virtual Common::Error saveGameState(int slot, const Common::String &desc); + + /** + * Called by the engine when sound settings are updated + */ virtual void syncSoundSettings(); + + /** + * Returns whether the version is a demo + */ virtual bool isDemo() const; + /** + * Returns the Id of the game + */ GameType getGameID() const; - Common::Language getLanguage() const; - Common::Platform getPlatform() const; - Common::String getGameFile(int fileType); + /** + * Returns the platform the game's datafiles are for + */ + Common::Platform getPlatform() const; + /** + * Return a random number + */ int getRandomNumber(int limit) { return _randomSource.getRandomNumber(limit - 1); } + /** + * Read the state of a global flag + * @remarks If a negative value is specified, it will return the inverse value + * of the positive flag number + */ bool readFlags(int flagNum); + /** + * Sets a global flag to either true or false depending on whether the specified + * flag is positive or negative + */ void setFlags(int flagNum); + /** + * Saves game configuration information + */ void saveConfig(); + /** + * Synchronize the data for a savegame + */ void synchronize(Common::Serializer &s); }; diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index 205178c0ec..2ed6a1bbe8 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -76,9 +76,6 @@ Sound::Sound(SherlockEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) { } } -/** - * Saves sound-related settings - */ void Sound::syncSoundSettings() { _digitized = !ConfMan.getBool("mute"); _music = !ConfMan.getBool("mute") && !ConfMan.getBool("music_mute"); diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index bff50d7a07..689e615a36 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -61,19 +61,61 @@ public: public: Sound(SherlockEngine *vm, Audio::Mixer *mixer); + /** + * Saves sound-related settings + */ void syncSoundSettings(); + + /** + * Load a sound + */ void loadSound(const Common::String &name, int priority); + + /** + * Play the sound in the specified resource + */ bool playSound(const Common::String &name, WaitType waitType, int priority = 100, const char *libraryFilename = nullptr); + + /** + * Play a previously loaded sound + */ void playLoadedSound(int bufNum, WaitType waitType); + + /** + * Free any previously loaded sounds + */ void freeLoadedSounds(); + + /** + * Stop playing any active sound + */ void stopSound(); + /** + * Load a specified song + */ int loadSong(int songNumber); + + /** + * Start playing a song + */ void startSong(); + + /** + * Free any currently loaded song + */ void freeSong(); + /** + * Play the specified music resource + */ void playMusic(const Common::String &name); + + /** + * Stop playing the music + */ void stopMusic(); + void stopSndFuncPtr(int v1, int v2); void waitTimerRoland(uint time); void freeDigiSound(); diff --git a/engines/sherlock/surface.cpp b/engines/sherlock/surface.cpp index eeaf304958..b54f43bf52 100644 --- a/engines/sherlock/surface.cpp +++ b/engines/sherlock/surface.cpp @@ -39,10 +39,6 @@ Surface::~Surface() { free(); } -/** - * Sets up an internal surface with the specified dimensions that will be automatically freed - * when the surface object is destroyed - */ void Surface::create(uint16 width, uint16 height) { if (_freePixels) free(); @@ -51,23 +47,14 @@ void Surface::create(uint16 width, uint16 height) { _freePixels = true; } -/** - * Copy a surface into this one - */ void Surface::blitFrom(const Graphics::Surface &src) { blitFrom(src, Common::Point(0, 0)); } -/** - * Draws a surface at a given position within this surface - */ void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt) { blitFrom(src, pt, Common::Rect(0, 0, src.w, src.h)); } -/** - * Draws a sub-section of a surface at a given position within this surface - */ void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds) { Common::Rect srcRect = srcBounds; @@ -80,17 +67,11 @@ void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt, } } -/** -* Draws an image frame at a given position within this surface with transparency -*/ void Surface::transBlitFrom(const ImageFrame &src, const Common::Point &pt, bool flipped, int overrideColor) { transBlitFrom(src._frame, pt + src._offset, flipped, overrideColor); } -/** -* Draws a surface at a given position within this surface with transparency -*/ void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &pt, bool flipped, int overrideColor) { Common::Rect drawRect(0, 0, src.w, src.h); @@ -125,24 +106,15 @@ void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &p } } -/** - * Fill a given area of the surface with a given color - */ void Surface::fillRect(int x1, int y1, int x2, int y2, byte color) { fillRect(Common::Rect(x1, y1, x2, y2), color); } -/** - * Fill a given area of the surface with a given color - */ void Surface::fillRect(const Common::Rect &r, byte color) { Graphics::Surface::fillRect(r, color); addDirtyRect(r); } -/** - * Clips the given source bounds so the passed destBounds will be entirely on-screen - */ bool Surface::clip(Common::Rect &srcBounds, Common::Rect &destBounds) { if (destBounds.left >= this->w || destBounds.top >= this->h || destBounds.right <= 0 || destBounds.bottom <= 0) @@ -172,9 +144,6 @@ bool Surface::clip(Common::Rect &srcBounds, Common::Rect &destBounds) { return true; } -/** - * Clear the screen - */ void Surface::clear() { fillRect(Common::Rect(0, 0, this->w, this->h), 0); } diff --git a/engines/sherlock/surface.h b/engines/sherlock/surface.h index b2a759aa8d..7049d8ae76 100644 --- a/engines/sherlock/surface.h +++ b/engines/sherlock/surface.h @@ -33,6 +33,9 @@ class Surface : public Graphics::Surface { private: bool _freePixels; + /** + * Clips the given source bounds so the passed destBounds will be entirely on-screen + */ bool clip(Common::Rect &srcBounds, Common::Rect &destBounds); protected: virtual void addDirtyRect(const Common::Rect &r) {} @@ -41,19 +44,53 @@ public: Surface(); virtual ~Surface(); + /** + * Sets up an internal surface with the specified dimensions that will be automatically freed + * when the surface object is destroyed + */ void create(uint16 width, uint16 height); + + /** + * Copy a surface into this one + */ void blitFrom(const Graphics::Surface &src); + + /** + * Draws a surface at a given position within this surface + */ void blitFrom(const Graphics::Surface &src, const Common::Point &pt); + + /** + * Draws a sub-section of a surface at a given position within this surface + */ void blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds); + + /** + * Draws an image frame at a given position within this surface with transparency + */ void transBlitFrom(const ImageFrame &src, const Common::Point &pt, bool flipped = false, int overrideColor = 0); + + /** + * Draws a surface at a given position within this surface with transparency + */ void transBlitFrom(const Graphics::Surface &src, const Common::Point &pt, bool flipped = false, int overrideColor = 0); + /** + * Fill a given area of the surface with a given color + */ void fillRect(int x1, int y1, int x2, int y2, byte color); + + /** + * Fill a given area of the surface with a given color + */ void fillRect(const Common::Rect &r, byte color); + /** + * Clear the screen + */ void clear(); }; diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index fd0b7cb378..734aa76e0a 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -36,9 +36,6 @@ SequenceEntry::SequenceEntry() { /*----------------------------------------------------------------*/ -/** - * Load the data for a single statement within a talk file - */ void Statement::synchronize(Common::SeekableReadStream &s) { int length; @@ -108,9 +105,6 @@ Talk::Talk(SherlockEngine *vm) : _vm(vm) { _scriptSaveIndex = -1; } -/** - * Sets talk sequences - */ void Talk::setSequences(const byte *talkSequences, const byte *stillSequences, int maxPeople) { for (int idx = 0; idx < maxPeople; ++idx) { STILL_SEQUENCES.push_back(TalkSequences(stillSequences)); @@ -120,14 +114,6 @@ void Talk::setSequences(const byte *talkSequences, const byte *stillSequences, i } } -/** - * Called whenever a conversation or item script needs to be run. For standard conversations, - * it opens up a description window similar to how 'talk' does, but shows a 'reply' directly - * instead of waiting for a statement option. - * @remarks It seems that at some point, all item scripts were set up to use this as well. - * In their case, the conversation display is simply suppressed, and control is passed on to - * doScript to implement whatever action is required. - */ void Talk::talkTo(const Common::String &filename) { Events &events = *_vm->_events; Inventory &inv = *_vm->_inventory; @@ -450,12 +436,6 @@ void Talk::talkTo(const Common::String &filename) { events.setCursor(ARROW); } -/** - * Main method for handling conversations when a character to talk to has been - * selected. It will make Holmes walk to the person to talk to, draws the - * interface window for the conversation and passes on control to give the - * player a list of options to make a selection from - */ void Talk::talk(int objNum) { Events &events = *_vm->_events; People &people = *_vm->_people; @@ -549,17 +529,10 @@ void Talk::talk(int objNum) { } } -/** - * Clear loaded talk data - */ void Talk::freeTalkVars() { _statements.clear(); } -/** - * Opens the talk file 'talk.tlk' and searches the index for the specified - * conversation. If found, the data for that conversation is loaded - */ void Talk::loadTalkFile(const Common::String &filename) { Resources &res = *_vm->_res; Sound &sound = *_vm->_sound; @@ -596,9 +569,6 @@ void Talk::loadTalkFile(const Common::String &filename) { setTalkMap(); } -/** - * Remove any voice commands from a loaded statement list - */ void Talk::stripVoiceCommands() { for (uint sIdx = 0; sIdx < _statements.size(); ++sIdx) { Statement &statement = _statements[sIdx]; @@ -622,9 +592,6 @@ void Talk::stripVoiceCommands() { } } -/** - * Form a table of the display indexes for statements - */ void Talk::setTalkMap() { int statementNum = 0; @@ -642,9 +609,6 @@ void Talk::setTalkMap() { } } -/** - * Draws the interface for conversation display - */ void Talk::drawInterface() { Screen &screen = *_vm->_screen; Surface &bb = *screen._backBuffer; @@ -673,10 +637,6 @@ void Talk::drawInterface() { } } -/** - * Display a list of statements in a window at the bottom of the screen that the - * player can select from. - */ bool Talk::displayTalk(bool slamIt) { Screen &screen = *_vm->_screen; int yp = CONTROLS_Y + 14; @@ -761,9 +721,6 @@ bool Talk::displayTalk(bool slamIt) { return done; } -/** - * Prints a single conversation option in the interface window - */ int Talk::talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt) { Screen &screen = *_vm->_screen; int idx = lineNum; @@ -852,17 +809,10 @@ int Talk::talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt return lineY; } -/** - * Clears the stack of pending object sequences associated with speakers in the scene - */ void Talk::clearSequences() { _sequenceStack.clear(); } -/** - * Pulls a background object sequence from the sequence stack and restore's the - * object's sequence - */ void Talk::pullSequence() { Scene &scene = *_vm->_scene; @@ -885,10 +835,6 @@ void Talk::pullSequence() { } } -/** - * Push the sequence of a background object that's an NPC that needs to be - * saved onto the sequence stack. - */ void Talk::pushSequence(int speaker) { People &people = *_vm->_people; Scene &scene = *_vm->_scene; @@ -918,9 +864,6 @@ void Talk::pushSequence(int speaker) { error("script stack overflow"); } -/** - * Change the sequence of the scene background object associated with the current speaker. - */ void Talk::setSequence(int speaker) { People &people = *_vm->_people; Scene &scene = *_vm->_scene; @@ -950,10 +893,6 @@ void Talk::setSequence(int speaker) { } } -/** - * Change the sequence of a background object corresponding to a given speaker. - * The new sequence will display the character as "listening" - */ void Talk::setStillSeq(int speaker) { People &people = *_vm->_people; Scene &scene = *_vm->_scene; @@ -983,10 +922,6 @@ void Talk::setStillSeq(int speaker) { } } -/** - * Parses a reply for control codes and display text. The found text is printed within - * the text window, handles delays, animations, and animating portraits. - */ void Talk::doScript(const Common::String &script) { Animation &anim = *_vm->_animation; Events &events = *_vm->_events; @@ -1631,10 +1566,6 @@ void Talk::doScript(const Common::String &script) { } } -/** - * When the talk window has been displayed, waits a period of time proportional to - * the amount of text that's been displayed - */ int Talk::waitForMore(int delay) { Events &events = *_vm->_events; People &people = *_vm->_people; @@ -1714,9 +1645,6 @@ int Talk::waitForMore(int delay) { return key2; } -/** - * Pops an entry off of the script stack - */ void Talk::popStack() { if (!_scriptStack.empty()) { ScriptStackEntry scriptEntry = _scriptStack.pop(); @@ -1727,9 +1655,6 @@ void Talk::popStack() { } } -/** - * Synchronize the data for a savegame - */ void Talk::synchronize(Common::Serializer &s) { for (int idx = 0; idx < MAX_TALK_FILES; ++idx) { TalkHistoryEntry &he = _talkHistory[idx]; diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index b1a735827c..71f093f66a 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -99,6 +99,9 @@ struct Statement { int _talkMap; Common::Rect _talkPos; + /** + * Load the data for a single statement within a talk file + */ void synchronize(Common::SeekableReadStream &s); }; @@ -141,15 +144,37 @@ private: int _talkToFlag; int _scriptSaveIndex; private: + /** + * Remove any voice commands from a loaded statement list + */ void stripVoiceCommands(); + + /** + * Form a table of the display indexes for statements + */ void setTalkMap(); + /** + * Display a list of statements in a window at the bottom of the screen that the + * player can select from. + */ bool displayTalk(bool slamIt); + /** + * Prints a single conversation option in the interface window + */ int talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt); + /** + * Parses a reply for control codes and display text. The found text is printed within + * the text window, handles delays, animations, and animating portraits. + */ void doScript(const Common::String &script); + /** + * When the talk window has been displayed, waits a period of time proportional to + * the amount of text that's been displayed + */ int waitForMore(int delay); public: bool _talkToAbort; @@ -161,30 +186,90 @@ public: int _converseNum; public: Talk(SherlockEngine *vm); + + /** + * Sets talk sequences + */ void setSequences(const byte *talkSequences, const byte *stillSequences, int maxPeople); Statement &operator[](int idx) { return _statements[idx]; } + /** + * Called whenever a conversation or item script needs to be run. For standard conversations, + * it opens up a description window similar to how 'talk' does, but shows a 'reply' directly + * instead of waiting for a statement option. + * @remarks It seems that at some point, all item scripts were set up to use this as well. + * In their case, the conversation display is simply suppressed, and control is passed on to + * doScript to implement whatever action is required. + */ void talkTo(const Common::String &filename); + /** + * Main method for handling conversations when a character to talk to has been + * selected. It will make Holmes walk to the person to talk to, draws the + * interface window for the conversation and passes on control to give the + * player a list of options to make a selection from + */ void talk(int objNum); + /** + * Clear loaded talk data + */ void freeTalkVars(); + /** + * Draws the interface for conversation display + */ void drawInterface(); + /** + * Opens the talk file 'talk.tlk' and searches the index for the specified + * conversation. If found, the data for that conversation is loaded + */ void loadTalkFile(const Common::String &filename); + /** + * Change the sequence of a background object corresponding to a given speaker. + * The new sequence will display the character as "listening" + */ void setStillSeq(int speaker); + + /** + * Clears the stack of pending object sequences associated with speakers in the scene + */ void clearSequences(); + + /** + * Pulls a background object sequence from the sequence stack and restore's the + * object's sequence + */ void pullSequence(); + + /** + * Push the sequence of a background object that's an NPC that needs to be + * saved onto the sequence stack. + */ void pushSequence(int speaker); + + /** + * Change the sequence of the scene background object associated with the current speaker. + */ void setSequence(int speaker); + + /** + * Returns true if the script stack is empty + */ bool isSequencesEmpty() const { return _scriptStack.empty(); } + /** + * Pops an entry off of the script stack + */ void popStack(); + /** + * Synchronize the data for a savegame + */ void synchronize(Common::Serializer &s); }; diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index ef1da3b29f..12054bd7fb 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -122,18 +122,12 @@ UserInterface::~UserInterface() { delete _controlPanel; } -/** - * Resets the user interface - */ void UserInterface::reset() { _oldKey = -1; _help = _oldHelp = -1; _oldTemp = _temp = -1; } -/** - * Draw the user interface onto the screen's back buffers - */ void UserInterface::drawInterface(int bufferNum) { Screen &screen = *_vm->_screen; @@ -145,9 +139,6 @@ void UserInterface::drawInterface(int bufferNum) { screen._backBuffer2.fillRect(0, INFO_LINE, SHERLOCK_SCREEN_WIDTH, INFO_LINE + 10, INFO_BLACK); } -/** - * Main input handler for the user interface - */ void UserInterface::handleInput() { Events &events = *_vm->_events; Inventory &inv = *_vm->_inventory; @@ -403,9 +394,6 @@ void UserInterface::handleInput() { } } -/** - * Draws the image for a user interface button in the down/pressed state. - */ void UserInterface::depressButton(int num) { Screen &screen = *_vm->_screen; Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]); @@ -415,10 +403,6 @@ void UserInterface::depressButton(int num) { screen.slamArea(pt.x, pt.y, pt.x + s.w, pt.y + s.h); } -/** - * Draws the image for the given user interface button in the up - * (not selected) position - */ void UserInterface::restoreButton(int num) { Screen &screen = *_vm->_screen; Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]); @@ -434,10 +418,6 @@ void UserInterface::restoreButton(int num) { } } -/** - * If he mouse button is pressed, then calls depressButton to draw the button - * as pressed; if not, it will show it as released with a call to "restoreButton". - */ void UserInterface::pushButton(int num) { Events &events = *_vm->_events; _oldKey = -1; @@ -455,11 +435,6 @@ void UserInterface::pushButton(int num) { restoreButton(num); } -/** - * By the time this method has been called, the graphics for the button change - * have already been drawn. This simply takes care of switching the mode around - * accordingly - */ void UserInterface::toggleButton(int num) { Screen &screen = *_vm->_screen; @@ -488,9 +463,6 @@ void UserInterface::toggleButton(int num) { } } -/** - * Clears the info line of the screen - */ void UserInterface::clearInfo() { if (_infoFlag) { _vm->_screen->vgaBar(Common::Rect(16, INFO_LINE, SHERLOCK_SCREEN_WIDTH - 19, @@ -500,9 +472,6 @@ void UserInterface::clearInfo() { } } -/** - * Clear any active text window - */ void UserInterface::clearWindow() { if (_windowOpen) { _vm->_screen->vgaBar(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, @@ -510,9 +479,6 @@ void UserInterface::clearWindow() { } } -/** - * Handles counting down whilst checking for input, then clears the info line. - */ void UserInterface::whileMenuCounter() { if (!(--_menuCounter) || _vm->_events->checkInput()) { _menuCounter = 0; @@ -521,10 +487,6 @@ void UserInterface::whileMenuCounter() { } } -/** - * Creates a text window and uses it to display the in-depth description - * of the highlighted object - */ void UserInterface::examine() { Events &events = *_vm->_events; Inventory &inv = *_vm->_inventory; @@ -576,9 +538,6 @@ void UserInterface::examine() { } } -/** - * Print the name of an object in the scene - */ void UserInterface::lookScreen(const Common::Point &pt) { Events &events = *_vm->_events; Inventory &inv = *_vm->_inventory; @@ -692,9 +651,6 @@ void UserInterface::lookScreen(const Common::Point &pt) { } } -/** - * Gets the item in the inventory the mouse is on and display's it's description - */ void UserInterface::lookInv() { Events &events = *_vm->_events; Inventory &inv = *_vm->_inventory; @@ -720,9 +676,6 @@ void UserInterface::lookInv() { } } -/** - * Handles input when the file list window is being displayed - */ void UserInterface::doEnvControl() { Events &events = *_vm->_events; SaveManager &saves = *_vm->_saves; @@ -1026,9 +979,6 @@ void UserInterface::doEnvControl() { } } -/** - * Handle input whilst the inventory is active - */ void UserInterface::doInvControl() { Events &events = *_vm->_events; Inventory &inv = *_vm->_inventory; @@ -1253,9 +1203,6 @@ void UserInterface::doInvControl() { } } -/** - * Handles waiting whilst an object's description window is open. - */ void UserInterface::doLookControl() { Events &events = *_vm->_events; Inventory &inv = *_vm->_inventory; @@ -1317,9 +1264,6 @@ void UserInterface::doLookControl() { } } -/** - * Handles input until one of the user interface buttons/commands is selected - */ void UserInterface::doMainControl() { Events &events = *_vm->_events; Inventory &inv = *_vm->_inventory; @@ -1458,9 +1402,6 @@ void UserInterface::doMainControl() { } } -/** - * Handles the input for the MOVE, OPEN, and CLOSE commands - */ void UserInterface::doMiscControl(int allowed) { Events &events = *_vm->_events; Scene &scene = *_vm->_scene; @@ -1510,9 +1451,6 @@ void UserInterface::doMiscControl(int allowed) { } } -/** - * Handles input for picking up items - */ void UserInterface::doPickControl() { Events &events = *_vm->_events; Scene &scene = *_vm->_scene; @@ -1536,10 +1474,6 @@ void UserInterface::doPickControl() { } } -/** - * Handles input when in talk mode. It highlights the buttons and available statements, - * and handles allowing the user to click on them - */ void UserInterface::doTalkControl() { Events &events = *_vm->_events; Journal &journal = *_vm->_journal; @@ -1790,12 +1724,6 @@ void UserInterface::doTalkControl() { } } -/** - * Handles events when the Journal is active. - * @remarks Whilst this would in theory be better in the Journal class, since it displays in - * the user interface, it uses so many internal UI fields, that it sort of made some sense - * to put it in the UserInterface class. - */ void UserInterface::journalControl() { Events &events = *_vm->_events; Journal &journal = *_vm->_journal; @@ -1844,9 +1772,6 @@ void UserInterface::journalControl() { screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } -/** -* Print the description of an object -*/ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { Events &events = *_vm->_events; Inventory &inv = *_vm->_inventory; @@ -2015,16 +1940,10 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { } } -/** - * Print the previously selected object's decription - */ void UserInterface::printObjectDesc() { printObjectDesc(_cAnimStr, true); } -/** - * Displays a passed window by gradually scrolling it vertically on-screen - */ void UserInterface::summonWindow(const Surface &bgSurface, bool slideUp) { Events &events = *_vm->_events; Screen &screen = *_vm->_screen; @@ -2065,9 +1984,6 @@ void UserInterface::summonWindow(const Surface &bgSurface, bool slideUp) { _windowOpen = true; } -/** - * Slide the window stored in the back buffer onto the screen - */ void UserInterface::summonWindow(bool slideUp, int height) { Screen &screen = *_vm->_screen; @@ -2085,10 +2001,6 @@ void UserInterface::summonWindow(bool slideUp, int height) { summonWindow(tempSurface, slideUp); } -/** - * Close a currently open window - * @param flag 0 = slide old window down, 1 = slide prior UI back up - */ void UserInterface::banishWindow(bool slideUp) { Events &events = *_vm->_events; Screen &screen = *_vm->_screen; @@ -2155,9 +2067,6 @@ void UserInterface::banishWindow(bool slideUp) { _menuMode = STD_MODE; } -/** - * Checks to see whether a USE action is valid on the given object - */ void UserInterface::checkUseAction(const UseType *use, const Common::String &invName, const char *const messages[], int objNum, int giveMode) { Events &events = *_vm->_events; @@ -2251,9 +2160,6 @@ void UserInterface::checkUseAction(const UseType *use, const Common::String &inv events.setCursor(ARROW); } -/** - * Called for OPEN, CLOSE, and MOVE actions are being done - */ void UserInterface::checkAction(ActionType &action, const char *const messages[], int objNum) { Events &events = *_vm->_events; People &people = *_vm->_people; diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index fdaa323e5e..068d1eaa99 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -90,29 +90,93 @@ private: int _find; int _oldUse; private: + /** + * Draws the image for a user interface button in the down/pressed state. + */ void depressButton(int num); + /** + * If he mouse button is pressed, then calls depressButton to draw the button + * as pressed; if not, it will show it as released with a call to "restoreButton". + */ void pushButton(int num); + /** + * By the time this method has been called, the graphics for the button change + * have already been drawn. This simply takes care of switching the mode around + * accordingly + */ void toggleButton(int num); + /** + * Creates a text window and uses it to display the in-depth description + * of the highlighted object + */ void examine(); + /** + * Print the name of an object in the scene + */ void lookScreen(const Common::Point &pt); + /** + * Gets the item in the inventory the mouse is on and display's it's description + */ void lookInv(); + /** + * Handles input when the file list window is being displayed + */ void doEnvControl(); + + /** + * Handle input whilst the inventory is active + */ void doInvControl(); + + /** + * Handles waiting whilst an object's description window is open. + */ void doLookControl(); + + /** + * Handles input until one of the user interface buttons/commands is selected + */ void doMainControl(); + + /** + * Handles the input for the MOVE, OPEN, and CLOSE commands + */ void doMiscControl(int allowed); + + /** + * Handles input for picking up items + */ void doPickControl(); + + /** + * Handles input when in talk mode. It highlights the buttons and available statements, + * and handles allowing the user to click on them + */ void doTalkControl(); + + /** + * Handles events when the Journal is active. + * @remarks Whilst this would in theory be better in the Journal class, since it displays in + * the user interface, it uses so many internal UI fields, that it sort of made some sense + * to put it in the UserInterface class. + */ void journalControl(); + /** + * Checks to see whether a USE action is valid on the given object + */ void checkUseAction(const UseType *use, const Common::String &invName, const char *const messages[], int objNum, int giveMode); + + /** + * Called for OPEN, CLOSE, and MOVE actions are being done + */ void checkAction(ActionType &action, const char *const messages[], int objNum); public: MenuMode _menuMode; @@ -128,24 +192,66 @@ public: UserInterface(SherlockEngine *vm); ~UserInterface(); + /** + * Resets the user interface + */ void reset(); + /** + * Draw the user interface onto the screen's back buffers + */ void drawInterface(int bufferNum = 3); + /** + * Main input handler for the user interface + */ void handleInput(); + /** + * Clears the info line of the screen + */ void clearInfo(); + + /** + * Clear any active text window + */ void clearWindow(); + /** + * Handles counting down whilst checking for input, then clears the info line. + */ void whileMenuCounter(); + /** + * Print the description of an object + */ void printObjectDesc(const Common::String &str, bool firstTime); + + /** + * Print the previously selected object's decription + */ void printObjectDesc(); + /** + * Displays a passed window by gradually scrolling it vertically on-screen + */ void summonWindow(const Surface &bgSurface, bool slideUp = true); + + /** + * Slide the window stored in the back buffer onto the screen + */ void summonWindow(bool slideUp = true, int height = CONTROLS_Y); + + /** + * Close a currently open window + * @param flag 0 = slide old window down, 1 = slide prior UI back up + */ void banishWindow(bool slideUp = true); + /** + * Draws the image for the given user interface button in the up + * (not selected) position + */ void restoreButton(int num); }; -- cgit v1.2.3 From 2752db8103c2076bc7838f6306de338f986f68a4 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 19 May 2015 07:50:50 -0400 Subject: SHERLOCK: Remove iimplicit conversion operator from ImageFrame --- engines/sherlock/events.cpp | 2 +- engines/sherlock/map.cpp | 6 +++--- engines/sherlock/resources.h | 2 -- engines/sherlock/surface.cpp | 13 +++++++++++++ engines/sherlock/surface.h | 23 +++++++++++++++++++---- 5 files changed, 36 insertions(+), 10 deletions(-) diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index 38093a6c72..b01437d54b 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -63,7 +63,7 @@ void Events::setCursor(CursorId cursorId) { _cursorId = cursorId; // Set the cursor data - Graphics::Surface &s = (*_cursorImages)[cursorId]; + Graphics::Surface &s = (*_cursorImages)[cursorId]._frame; setCursor(s); } diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index 737abb4895..ae19e65280 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -228,7 +228,7 @@ int Map::show() { // Show wait cursor _cursorIndex = 1; - events.setCursor((*_mapCursors)[_cursorIndex]); + events.setCursor((*_mapCursors)[_cursorIndex]._frame); } } @@ -269,7 +269,7 @@ void Map::setupSprites() { _mapCursors = new ImageFile("omouse.vgs"); _cursorIndex = 0; - events.setCursor((*_mapCursors)[_cursorIndex]); + events.setCursor((*_mapCursors)[_cursorIndex]._frame); _shapes = new ImageFile("mapicon.vgs"); _iconShapes = new ImageFile("overicon.vgs"); @@ -369,7 +369,7 @@ void Map::updateMap(bool flushScreen) { if (++_cursorIndex > (1 + 8)) _cursorIndex = 1; - events.setCursor((*_mapCursors)[(_cursorIndex + 1) / 2]); + events.setCursor((*_mapCursors)[(_cursorIndex + 1) / 2]._frame); } if (!_drawMap && !flushScreen) diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h index 4ca4038529..fb91b30f94 100644 --- a/engines/sherlock/resources.h +++ b/engines/sherlock/resources.h @@ -158,8 +158,6 @@ struct ImageFrame { Common::Point _offset; byte _rleMarker; Graphics::Surface _frame; - - operator Graphics::Surface &() { return _frame; } }; class ImageFile : public Common::Array { diff --git a/engines/sherlock/surface.cpp b/engines/sherlock/surface.cpp index b54f43bf52..83d4b78a0a 100644 --- a/engines/sherlock/surface.cpp +++ b/engines/sherlock/surface.cpp @@ -22,6 +22,7 @@ #include "sherlock/surface.h" #include "sherlock/sherlock.h" +#include "sherlock/resources.h" #include "common/system.h" #include "graphics/palette.h" @@ -51,10 +52,18 @@ void Surface::blitFrom(const Graphics::Surface &src) { blitFrom(src, Common::Point(0, 0)); } +void Surface::blitFrom(const ImageFrame &src) { + blitFrom(src._frame, Common::Point(0, 0)); +} + void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt) { blitFrom(src, pt, Common::Rect(0, 0, src.w, src.h)); } +void Surface::blitFrom(const ImageFrame &src, const Common::Point &pt) { + blitFrom(src._frame, pt, Common::Rect(0, 0, src._frame.w, src._frame.h)); +} + void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds) { Common::Rect srcRect = srcBounds; @@ -67,6 +76,10 @@ void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt, } } +void Surface::blitFrom(const ImageFrame &src, const Common::Point &pt, const Common::Rect &srcBounds) { + blitFrom(src._frame, pt, srcBounds); +} + void Surface::transBlitFrom(const ImageFrame &src, const Common::Point &pt, bool flipped, int overrideColor) { transBlitFrom(src._frame, pt + src._offset, flipped, overrideColor); diff --git a/engines/sherlock/surface.h b/engines/sherlock/surface.h index 7049d8ae76..4b7166b090 100644 --- a/engines/sherlock/surface.h +++ b/engines/sherlock/surface.h @@ -25,10 +25,11 @@ #include "common/rect.h" #include "graphics/surface.h" -#include "sherlock/resources.h" namespace Sherlock { +struct ImageFrame; + class Surface : public Graphics::Surface { private: bool _freePixels; @@ -55,17 +56,31 @@ public: */ void blitFrom(const Graphics::Surface &src); + /** + * Copy an image frame into this surface + */ + void blitFrom(const ImageFrame &src); + /** * Draws a surface at a given position within this surface */ void blitFrom(const Graphics::Surface &src, const Common::Point &pt); + /** + * Copy an image frame onto this surface at a given position + */ + void blitFrom(const ImageFrame &src, const Common::Point &pt); + /** * Draws a sub-section of a surface at a given position within this surface */ - void blitFrom(const Graphics::Surface &src, const Common::Point &pt, - const Common::Rect &srcBounds); - + void blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds); + + /** + * Copy a sub-area of a source image frame into this surface at a given position + */ + void blitFrom(const ImageFrame &src, const Common::Point &pt, const Common::Rect &srcBounds); + /** * Draws an image frame at a given position within this surface with transparency */ -- cgit v1.2.3 From dac49ddab496b9e5ca0f6589ea7b5ad906faa464 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 19 May 2015 07:53:45 -0400 Subject: SHERLOCK: Syntactic fix and define for SaveManager --- engines/sherlock/saveload.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index bec832aa05..053c52c4e5 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -38,6 +38,10 @@ const int ENV_POINTS[6][3] = { { 241, 280, 261 } // Quit }; +const char *const SAVEGAME_STR = "SHLK"; +#define SAVEGAME_STR_SIZE 4 +#define ONSCREEN_FILES_COUNT 5 + /*----------------------------------------------------------------*/ SaveManager::SaveManager(SherlockEngine *vm, const Common::String &target) : @@ -84,11 +88,10 @@ void SaveManager::drawInterface() { if (!_savegameIndex) screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), COMMAND_NULL, 0, "Up"); - if (_savegameIndex == MAX_SAVEGAME_SLOTS - 5) + if (_savegameIndex == MAX_SAVEGAME_SLOTS - ONSCREEN_FILES_COUNT) screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), COMMAND_NULL, 0, "Down"); - for (int idx = _savegameIndex; idx < _savegameIndex + 5; ++idx) - { + for (int idx = _savegameIndex; idx < _savegameIndex + ONSCREEN_FILES_COUNT; ++idx) { screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10), INV_FOREGROUND, "%d.", idx + 1); screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10), @@ -163,9 +166,6 @@ SaveStateList SaveManager::getSavegameList(const Common::String &target) { return saveList; } -const char *const SAVEGAME_STR = "SHLK"; -#define SAVEGAME_STR_SIZE 4 - bool SaveManager::readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header) { char saveIdentBuffer[SAVEGAME_STR_SIZE + 1]; header._thumbnail = nullptr; -- cgit v1.2.3 From fa35249a240d7bdfe5f5b7eb9ae073126d5080c4 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 19 May 2015 08:01:06 -0400 Subject: SHERLOCK: More syntactic fixes --- engines/sherlock/journal.cpp | 4 ++-- engines/sherlock/saveload.cpp | 6 +++--- engines/sherlock/saveload.h | 2 +- engines/sherlock/scalpel/scalpel.cpp | 17 +++++++++-------- engines/sherlock/user_interface.cpp | 4 ++-- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 0a0144996d..7afa60d396 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -1121,8 +1121,8 @@ int Journal::getSearchString(bool printError) { } else if (keyState.keycode == Common::KEYCODE_ESCAPE) { screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), BUTTON_MIDDLE); done = -1; - } else if (keyState.ascii >= ' ' && keyState.keycode <= 'z' && keyState.keycode != Common::KEYCODE_AT && - name.size() < JOURNAL_SEACRH_MAX_CHARS && (xp + screen.charWidth(keyState.keycode)) < JOURNAL_SEARCH_RIGHT) { + } else if (keyState.ascii >= ' ' && keyState.ascii <= 'z' && keyState.keycode != Common::KEYCODE_AT && + name.size() < JOURNAL_SEACRH_MAX_CHARS && (xp + screen.charWidth(keyState.ascii)) < JOURNAL_SEARCH_RIGHT) { char ch = toupper(keyState.ascii); screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), BUTTON_MIDDLE); screen.print(Common::Point(xp, yp), TALK_FOREGROUND, "%c", ch); diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index 053c52c4e5..63d3142262 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -385,7 +385,7 @@ bool SaveManager::checkGameOnScreen(int slot) { return false; } -bool SaveManager::getFilename(int slot) { +bool SaveManager::promptForFilename(int slot) { Events &events = *_vm->_events; Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; @@ -455,8 +455,8 @@ bool SaveManager::getFilename(int slot) { done = -1; } - if (keyState.keycode >= ' ' && keyState.keycode <= 'z' && saveName.size() < 50 - && (xp + screen.charWidth(keyState.keycode)) < 308) { + if (keyState.ascii >= ' ' && keyState.ascii <= 'z' && saveName.size() < 50 + && (xp + screen.charWidth(keyState.ascii)) < 308) { char c = (char)keyState.ascii; screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_BACKGROUND); diff --git a/engines/sherlock/saveload.h b/engines/sherlock/saveload.h index 371a6e4c79..07626a2082 100644 --- a/engines/sherlock/saveload.h +++ b/engines/sherlock/saveload.h @@ -133,7 +133,7 @@ public: /** * Prompts the user to enter a filename in a given slot */ - bool getFilename(int slot); + bool promptForFilename(int slot); }; } // End of namespace Sherlock diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 170768d91d..1f83ca4872 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -63,24 +63,25 @@ static const int TITLE_FRAMES[7][9] = { }; #define NUM_PLACES 100 -const int MAP_X[NUM_PLACES] = { + +static const int MAP_X[NUM_PLACES] = { 0, 368, 0, 219, 0, 282, 0, 43, 0, 0, 396, 408, 0, 0, 0, 568, 37, 325, 28, 0, 263, 36, 148, 469, 342, 143, 443, 229, 298, 0, 157, 260, 432, 174, 0, 351, 0, 528, 0, 136, 0, 0, 0, 555, 165, 0, 506, 0, 0, 344, 0, 0 }; -const int MAP_Y[NUM_PLACES] = { +static const int MAP_Y[NUM_PLACES] = { 0, 147, 0, 166, 0, 109, 0, 61, 0, 0, 264, 70, 0, 0, 0, 266, 341, 30, 275, 0, 294, 146, 311, 230, 184, 268, 133, 94, 207, 0, 142, 142, 330, 255, 0, 37, 0, 70, 0, 116, 0, 0, 0, 50, 21, 0, 303, 0, 0, 229, 0, 0 }; -const int MAP_TRANSLATE[NUM_PLACES] = { +static const int MAP_TRANSLATE[NUM_PLACES] = { 0, 0, 0, 1, 0, 2, 0, 3, 4, 0, 4, 6, 0, 0, 0, 8, 9, 10, 11, 0, 12, 13, 14, 7, 15, 16, 17, 18, 19, 0, 20, 21, 22, 23, 0, 24, 0, 25, 0, 26, 0, 0, 0, 27, 28, 0, 29, 0, 0, 30, 0 }; -const byte MAP_SEQUENCES[3][MAX_FRAME] = { +static const byte MAP_SEQUENCES[3][MAX_FRAME] = { { 1, 1, 2, 3, 4, 0 }, // Overview Still { 5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 0 }, { 5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 0 } @@ -88,7 +89,7 @@ const byte MAP_SEQUENCES[3][MAX_FRAME] = { #define MAX_PEOPLE 66 -const byte STILL_SEQUENCES[MAX_PEOPLE][MAX_TALK_SEQUENCES] = { +static const byte STILL_SEQUENCES[MAX_PEOPLE][MAX_TALK_SEQUENCES] = { { 1, 0, 0 }, // Sherlock Holmes { 6, 0, 0 }, // Dr. Watson { 4, 0, 0 }, // Inspector Lestrade @@ -157,7 +158,7 @@ const byte STILL_SEQUENCES[MAX_PEOPLE][MAX_TALK_SEQUENCES] = { { 4, 0, 0 } // Inspector Lestrade (Yard) }; -byte TALK_SEQUENCES[MAX_PEOPLE][MAX_TALK_SEQUENCES] = { +static const byte TALK_SEQUENCES[MAX_PEOPLE][MAX_TALK_SEQUENCES] = { { 1, 0, 0 }, // Sherlock Holmes { 5, 5, 6, 7, 8, 7, 8, 6, 0, 0 }, // Dr. Watson { 2, 0, 0 }, // Inspector Lestrade @@ -381,12 +382,12 @@ bool ScalpelEngine::showAlleyCutscene() { if (finished) finished = _animation->play("27PRO3", 1, 0, true, 2); - if(finished) { + if (finished) { _screen->getPalette(palette); _screen->fadeToBlack(2); } - if(finished) { + if (finished) { ImageFile titleImages("title3.vgs", true); // "Early the following morning on Baker Street..." _screen->_backBuffer1.transBlitFrom(titleImages[0], Common::Point(35, 51), false, 0); diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 12054bd7fb..861c1c695d 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -783,7 +783,7 @@ void UserInterface::doEnvControl() { if (saves.checkGameOnScreen(_selector)) _oldSelector = _selector; - if (saves.getFilename(_selector)) { + if (saves.promptForFilename(_selector)) { saves.saveGame(_selector + 1, saves._savegames[_selector]); banishWindow(1); @@ -954,7 +954,7 @@ void UserInterface::doEnvControl() { if (saves.checkGameOnScreen(_selector)) _oldSelector = _selector; - if (saves.getFilename(_selector)) { + if (saves.promptForFilename(_selector)) { saves.saveGame(_selector + 1, saves._savegames[_selector]); banishWindow(); _windowBounds.top = CONTROLS_Y1; -- cgit v1.2.3 From 1c395b4de91f3edb0ad7109da016eb42a32b434b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 19 May 2015 08:13:46 -0400 Subject: SHERLOCK: Add extra constants for object bit-flags --- engines/sherlock/events.cpp | 8 ++++---- engines/sherlock/objects.cpp | 10 ++++----- engines/sherlock/objects.h | 2 +- engines/sherlock/scene.cpp | 48 +++++++++++++++++++++++--------------------- 4 files changed, 35 insertions(+), 33 deletions(-) diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index b01437d54b..94ddc9a792 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -214,18 +214,18 @@ bool Events::delay(uint32 time, bool interruptable) { void Events::setButtonState() { _released = _rightReleased = false; - if (_mouseButtons & 1) + if (_mouseButtons & LEFT_BUTTON) _pressed = _oldButtons = true; - if ((_mouseButtons & 1) == 0 && _oldButtons) { + if ((_mouseButtons & LEFT_BUTTON) == 0 && _oldButtons) { _pressed = _oldButtons = false; _released = true; } - if (_mouseButtons & 2) + if (_mouseButtons & RIGHT_BUTTON) _rightPressed = _oldRightButton = true; - if ((_mouseButtons & 2) == 0 && _oldRightButton) { + if ((_mouseButtons & RIGHT_BUTTON) == 0 && _oldRightButton) { _rightPressed = _oldRightButton = false; _rightReleased = true; } diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index e630b48f3a..94457b3dd5 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -575,7 +575,7 @@ void Object::checkObject() { _seqCounter2 = _seqCounter; _seqStack = _frameNumber + 1; setObjSequence(v, false); - } else if (v >= SOUND_CODE && (v <= (SOUND_CODE + 29))) { + } else if (v >= SOUND_CODE && (v < (SOUND_CODE + 30))) { codeFound = true; ++_frameNumber; v -= SOUND_CODE; @@ -584,7 +584,7 @@ void Object::checkObject() { if (!scene._sounds[v - 1]._name.empty() && sound._digitized) sound.playLoadedSound(v - 1, WAIT_RETURN_IMMEDIATELY); } - } else if (v >= FLIP_CODE && v <= (FLIP_CODE + 2)) { + } else if (v >= FLIP_CODE && v < (FLIP_CODE + 3)) { // Flip code codeFound = true; ++_frameNumber; @@ -594,15 +594,15 @@ void Object::checkObject() { switch (v) { case 0: // Clear the flag - _flags &= ~2; + _flags &= ~OBJ_FLIPPED; break; case 1: // Set the flag - _flags |= 2; + _flags |= OBJ_FLIPPED; break; case 2: // Toggle the flag - _flags ^= 2; + _flags ^= OBJ_FLIPPED; break; default: break; diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 53752a7351..6dbe645d4b 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -189,7 +189,7 @@ struct UseType { void load(Common::SeekableReadStream &s); }; -enum { TURNON_OBJ = 0x20, TURNOFF_OBJ = 0x40 }; +enum { OBJ_BEHIND = 1, OBJ_FLIPPED = 2, OBJ_FORWARD = 4, TURNON_OBJ = 0x20, TURNOFF_OBJ = 0x40 }; #define USE_COUNT 4 class Object { diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 5ac43fc1be..d835b5caa8 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -727,27 +727,27 @@ void Scene::updateBackground() { // Draw all active shapes which are behind the person for (uint idx = 0; idx < _bgShapes.size(); ++idx) { if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE && _bgShapes[idx]._misc == BEHIND) - screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); + screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & OBJ_FLIPPED); } // Draw all canimations which are behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if (_canimShapes[idx]._type == ACTIVE_BG_SHAPE && _canimShapes[idx]._misc == BEHIND) screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame, - _canimShapes[idx]._position, _canimShapes[idx]._flags & 2); + _canimShapes[idx]._position, _canimShapes[idx]._flags & OBJ_FLIPPED); } // Draw all active shapes which are normal and behind the person for (uint idx = 0; idx < _bgShapes.size(); ++idx) { if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE && _bgShapes[idx]._misc == NORMAL_BEHIND) - screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); + screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & OBJ_FLIPPED); } // Draw all canimations which are normal and behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if (_canimShapes[idx]._type == ACTIVE_BG_SHAPE && _canimShapes[idx]._misc == NORMAL_BEHIND) screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, - _canimShapes[idx]._flags & 2); + _canimShapes[idx]._flags & OBJ_FLIPPED); } // Draw the player if he's active @@ -764,7 +764,8 @@ void Scene::updateBackground() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { if ((_bgShapes[idx]._type == ACTIVE_BG_SHAPE || _bgShapes[idx]._type == STATIC_BG_SHAPE) && _bgShapes[idx]._misc == NORMAL_FORWARD) - screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); + screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, + _bgShapes[idx]._flags & OBJ_FLIPPED); } // Draw all static and active canimations that are NORMAL and are in front of the player @@ -772,7 +773,7 @@ void Scene::updateBackground() { if ((_canimShapes[idx]._type == ACTIVE_BG_SHAPE || _canimShapes[idx]._type == STATIC_BG_SHAPE) && _canimShapes[idx]._misc == NORMAL_FORWARD) screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, - _canimShapes[idx]._flags & 2); + _canimShapes[idx]._flags & OBJ_FLIPPED); } // Draw all static and active shapes that are FORWARD @@ -783,7 +784,8 @@ void Scene::updateBackground() { if ((_bgShapes[idx]._type == ACTIVE_BG_SHAPE || _bgShapes[idx]._type == STATIC_BG_SHAPE) && _bgShapes[idx]._misc == FORWARD) - screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & 2); + screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, + _bgShapes[idx]._flags & OBJ_FLIPPED); } // Draw all static and active canimations that are forward @@ -791,7 +793,7 @@ void Scene::updateBackground() { if ((_canimShapes[idx]._type == ACTIVE_BG_SHAPE || _canimShapes[idx]._type == STATIC_BG_SHAPE) && _canimShapes[idx]._misc == FORWARD) screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position, - _canimShapes[idx]._flags & 2); + _canimShapes[idx]._flags & OBJ_FLIPPED); } screen.resetDisplayBounds(); @@ -814,9 +816,9 @@ void Scene::checkBgShapes(ImageFrame *frame, const Common::Point &pt) { if ((obj._flags & 5) == 1) { obj._misc = (pt.y < (obj._position.y + obj.frameHeight() - 1)) ? NORMAL_FORWARD : NORMAL_BEHIND; - } else if (!(obj._flags & 1)) { + } else if (!(obj._flags & OBJ_BEHIND)) { obj._misc = BEHIND; - } else if (obj._flags & 4) { + } else if (obj._flags & OBJ_FORWARD) { obj._misc = FORWARD; } } @@ -1147,7 +1149,7 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; - if (o._type == NO_SHAPE && ((o._flags & 1) == 0)) { + if (o._type == NO_SHAPE && ((o._flags & OBJ_BEHIND) == 0)) { // Restore screen area screen._backBuffer->blitFrom(screen._backBuffer2, o._position, Common::Rect(o._position.x, o._position.y, @@ -1198,14 +1200,14 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == BEHIND) - screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); } // Draw all canimations which are behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == BEHIND) { - screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); } } @@ -1213,14 +1215,14 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == NORMAL_BEHIND) - screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); } // Draw all canimations which are NORMAL and behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == NORMAL_BEHIND) { - screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); } } @@ -1241,14 +1243,14 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == NORMAL_FORWARD) - screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); } // Draw all static and active canimations that are NORMAL and are in front of the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == NORMAL_FORWARD) { - screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); } } @@ -1256,27 +1258,27 @@ void Scene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == FORWARD) - screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); } // Draw any active portrait if (people._portraitLoaded && people._portrait._type == ACTIVE_BG_SHAPE) screen._backBuffer->transBlitFrom(*people._portrait._imageFrame, - people._portrait._position, people._portrait._flags & 2); + people._portrait._position, people._portrait._flags & OBJ_FLIPPED); // Draw all static and active canimations that are in front of the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = _canimShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == FORWARD) { - screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); } } // Draw all NO_SHAPE shapes which have flag bit 0 clear for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; - if (o._type == NO_SHAPE && (o._flags & 1) == 0) - screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & 2); + if (o._type == NO_SHAPE && (o._flags & OBJ_BEHIND) == 0) + screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); } // Bring the newly built picture to the screen @@ -1331,7 +1333,7 @@ void Scene::doBgAnim() { if (_goToScene == -1) { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; - if (o._type == NO_SHAPE && (o._flags & 1) == 0) { + if (o._type == NO_SHAPE && (o._flags & OBJ_BEHIND) == 0) { screen.slamArea(o._position.x, o._position.y, o._oldSize.x, o._oldSize.y); screen.slamArea(o._oldPosition.x, o._oldPosition.y, o._oldSize.x, o._oldSize.y); } else if (o._type == HIDE_SHAPE) { -- cgit v1.2.3 From 8ae0014bc25e42e519d5a6a31279ee22580aaba9 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 19 May 2015 09:10:35 -0400 Subject: SHERLOCK: Refactor Surface not to descend directly from Graphics::Surface --- engines/sherlock/animation.cpp | 2 +- engines/sherlock/inventory.cpp | 15 ++++----- engines/sherlock/map.cpp | 10 +++--- engines/sherlock/scalpel/darts.cpp | 8 ++--- engines/sherlock/scalpel/scalpel.cpp | 10 +++--- engines/sherlock/screen.cpp | 16 +++------ engines/sherlock/surface.cpp | 63 +++++++++++++++++++++++++----------- engines/sherlock/surface.h | 56 ++++++++++++++++++++++++++++---- engines/sherlock/user_interface.cpp | 39 +++++++++++----------- 9 files changed, 139 insertions(+), 80 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 21d63633d3..7c1f2cd229 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -88,7 +88,7 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade, // Draw the sprite. Note that we explicitly use the raw frame below, rather than the ImageFrame, // since we don't want the offsets in the image file to be used, just the explicit position we specify - screen.transBlitFrom(images[imageFrame]._frame, pt); + screen.transBlitFrom(images[imageFrame], pt); } else { // At this point, either the sprites for the frame has been complete, or there weren't any sprites // at all to draw for the frame diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index 28065a1b72..63642f4e5a 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -155,9 +155,9 @@ void Inventory::putInv(InvSlamMode slamIt) { } // Draw the item image - Graphics::Surface &img = (*_invShapes[itemNum])[0]._frame; - bb.transBlitFrom(img, Common::Point(6 + itemNum * 52 + ((47 - img.w) / 2), - 163 + ((33 - img.h) / 2))); + ImageFrame &frame = (*_invShapes[itemNum])[0]; + bb.transBlitFrom(frame, Common::Point(6 + itemNum * 52 + ((47 - frame._width) / 2), + 163 + ((33 - frame._height) / 2))); } if (slamIt == SLAM_DISPLAY) @@ -307,11 +307,11 @@ void Inventory::highlight(int index, byte color) { Screen &screen = *_vm->_screen; Surface &bb = *screen._backBuffer; int slot = index - _invIndex; - Graphics::Surface &img = (*_invShapes[slot])[0]._frame; + ImageFrame &frame = (*_invShapes[slot])[0]; bb.fillRect(Common::Rect(8 + slot * 52, 165, (slot + 1) * 52, 194), color); - bb.transBlitFrom(img, Common::Point(6 + slot * 52 + ((47 - img.w) / 2), - 163 + ((33 - img.h) / 2))); + bb.transBlitFrom(frame, Common::Point(6 + slot * 52 + ((47 - frame._width) / 2), + 163 + ((33 - frame._height) / 2))); screen.slamArea(8 + slot * 52, 165, 44, 30); } @@ -331,8 +331,7 @@ void Inventory::refreshInv() { ui.examine(); if (!talk._talkToAbort) { - screen._backBuffer2.blitFrom((*ui._controlPanel)[0]._frame, - Common::Point(0, CONTROLS_Y)); + screen._backBuffer2.blitFrom((*ui._controlPanel)[0], Common::Point(0, CONTROLS_Y)); loadInv(); } } diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index ae19e65280..ed2912edc9 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -329,7 +329,7 @@ void Map::saveTopLine() { void Map::eraseTopLine() { Screen &screen = *_vm->_screen; screen._backBuffer1.blitFrom(_topLine, Common::Point(0, 0)); - screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, _topLine.h); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, _topLine.h()); } void Map::showPlaceName(int idx, bool highlighted) { @@ -344,7 +344,7 @@ void Map::showPlaceName(int idx, bool highlighted) { bool flipped = people[AL]._sequenceNumber == MAP_DOWNLEFT || people[AL]._sequenceNumber == MAP_LEFT || people[AL]._sequenceNumber == MAP_UPLEFT; - screen._backBuffer1.transBlitFrom(people[AL]._imageFrame->_frame, _lDrawnPos, flipped); + screen._backBuffer1.transBlitFrom(*people[AL]._imageFrame, _lDrawnPos, flipped); } if (highlighted) { @@ -386,9 +386,9 @@ void Map::updateMap(bool flushScreen) { saveIcon(people[AL]._imageFrame, hPos); if (people[AL]._sequenceNumber == MAP_DOWNLEFT || people[AL]._sequenceNumber == MAP_LEFT || people[AL]._sequenceNumber == MAP_UPLEFT) - screen._backBuffer1.transBlitFrom(people[AL]._imageFrame->_frame, hPos, true); + screen._backBuffer1.transBlitFrom(*people[AL]._imageFrame, hPos, true); else - screen._backBuffer1.transBlitFrom(people[AL]._imageFrame->_frame, hPos, false); + screen._backBuffer1.transBlitFrom(*people[AL]._imageFrame, hPos, false); if (flushScreen) { screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); @@ -488,7 +488,7 @@ void Map::saveIcon(ImageFrame *src, const Common::Point &pt) { return; } - assert(size.x <= _iconSave.w && size.y <= _iconSave.h); + assert(size.x <= _iconSave.w() && size.y <= _iconSave.h()); _iconSave.blitFrom(screen._backBuffer1, Common::Point(0, 0), Common::Rect(pos.x, pos.y, pos.x + size.x, pos.y + size.y)); _savedPos = pos; diff --git a/engines/sherlock/scalpel/darts.cpp b/engines/sherlock/scalpel/darts.cpp index e861b9cd62..23ca95454f 100644 --- a/engines/sherlock/scalpel/darts.cpp +++ b/engines/sherlock/scalpel/darts.cpp @@ -332,7 +332,7 @@ void Darts::drawDartThrow(const Common::Point &pt) { int delta = 9; for (int idx = 4; idx < 23; ++idx) { - Graphics::Surface &frame = (*_dartImages)[idx]._frame; + ImageFrame &frame = (*_dartImages)[idx]; // Adjust draw position for animating dart if (idx < 13) @@ -343,15 +343,15 @@ void Darts::drawDartThrow(const Common::Point &pt) { pos.y += delta++; // Draw the dart - Common::Point drawPos(pos.x - frame.w / 2, pos.y - frame.h); + Common::Point drawPos(pos.x - frame._width / 2, pos.y - frame._height); screen._backBuffer1.transBlitFrom(frame, drawPos); - screen.slamArea(drawPos.x, drawPos.y, frame.w, frame.h); + screen.slamArea(drawPos.x, drawPos.y, frame._width, frame._height); // Handle erasing old dart strs if (!oldDrawBounds.isEmpty()) screen.slamRect(oldDrawBounds); - oldDrawBounds = Common::Rect(drawPos.x, drawPos.y, drawPos.x + frame.w, drawPos.y + frame.h); + oldDrawBounds = Common::Rect(drawPos.x, drawPos.y, drawPos.x + frame._width, drawPos.y + frame._height); screen._backBuffer1.blitFrom(screen._backBuffer2, drawPos, oldDrawBounds); events.wait(2); diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 1f83ca4872..56c1e28dbe 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -301,8 +301,8 @@ bool ScalpelEngine::showCityCutscene() { if (finished) { ImageFile titleImages("title2.vgs", true); - _screen->_backBuffer1.copyFrom(*_screen); - _screen->_backBuffer2.copyFrom(*_screen); + _screen->_backBuffer1.blitFrom(*_screen); + _screen->_backBuffer2.blitFrom(*_screen); // London, England _screen->_backBuffer1.transBlitFrom(titleImages[0], Common::Point(10, 11)); @@ -326,8 +326,8 @@ bool ScalpelEngine::showCityCutscene() { if (finished) { ImageFile titleImages("title.vgs", true); - _screen->_backBuffer1.copyFrom(*_screen); - _screen->_backBuffer2.copyFrom(*_screen); + _screen->_backBuffer1.blitFrom(*_screen); + _screen->_backBuffer2.blitFrom(*_screen); // The Lost Files of _screen->_backBuffer1.transBlitFrom(titleImages[0], Common::Point(75, 6)); @@ -519,7 +519,7 @@ void ScalpelEngine::showLBV(const Common::String &filename) { delete stream; _screen->setPalette(images._palette); - _screen->_backBuffer1.blitFrom(images[0]._frame); + _screen->_backBuffer1.blitFrom(images[0]); _screen->verticalTransition(); } diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 583ac5b485..1d3c0e0dbf 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -39,10 +39,6 @@ Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCR Common::fill(&_cMap[0], &_cMap[PALETTE_SIZE], 0); Common::fill(&_sMap[0], &_sMap[PALETTE_SIZE], 0); setFont(1); - - // Set dummy surface used for restricted scene drawing - _sceneSurface.format = Graphics::PixelFormat::createFormatCLUT8(); - _sceneSurface.pitch = SHERLOCK_SCREEN_WIDTH; } Screen::~Screen() { @@ -76,7 +72,7 @@ void Screen::update() { for (i = _dirtyRects.begin(); i != _dirtyRects.end(); ++i) { const Common::Rect &r = *i; const byte *srcP = (const byte *)getBasePtr(r.left, r.top); - g_system->copyRectToScreen(srcP, this->pitch, r.left, r.top, + g_system->copyRectToScreen(srcP, _surface.pitch, r.left, r.top, r.width(), r.height()); } @@ -126,7 +122,7 @@ void Screen::fadeToBlack(int speed) { } setPalette(tempPalette); - fillRect(Common::Rect(0, 0, this->w, this->h), 0); + fillRect(Common::Rect(0, 0, _surface.w, _surface.h), 0); } void Screen::fadeIn(const byte palette[PALETTE_SIZE], int speed) { @@ -189,7 +185,7 @@ void Screen::randomTransition() { if (idx != 0 && (idx % 300) == 0) { // Ensure there's a full screen dirty rect for the next frame update if (_dirtyRects.empty()) - addDirtyRect(Common::Rect(0, 0, this->w, this->h)); + addDirtyRect(Common::Rect(0, 0, _surface.w, _surface.h)); events.pollEvents(); events.delay(1); @@ -409,9 +405,7 @@ void Screen::makeField(const Common::Rect &r) { void Screen::setDisplayBounds(const Common::Rect &r) { assert(r.left == 0 && r.top == 0); - _sceneSurface.setPixels(_backBuffer1.getPixels()); - _sceneSurface.w = r.width(); - _sceneSurface.h = r.height(); + _sceneSurface.setPixels(_backBuffer1.getPixels(), r.width(), r.height()); _backBuffer = &_sceneSurface; } @@ -421,7 +415,7 @@ void Screen::resetDisplayBounds() { } Common::Rect Screen::getDisplayBounds() { - return (_backBuffer == &_sceneSurface) ? Common::Rect(0, 0, _sceneSurface.w, _sceneSurface.h) : + return (_backBuffer == &_sceneSurface) ? Common::Rect(0, 0, _sceneSurface.w(), _sceneSurface.h()) : Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } diff --git a/engines/sherlock/surface.cpp b/engines/sherlock/surface.cpp index 83d4b78a0a..9214a75ded 100644 --- a/engines/sherlock/surface.cpp +++ b/engines/sherlock/surface.cpp @@ -37,18 +37,18 @@ Surface::Surface() : _freePixels(false) { Surface::~Surface() { if (_freePixels) - free(); + _surface.free(); } void Surface::create(uint16 width, uint16 height) { if (_freePixels) - free(); + _surface.free(); - Graphics::Surface::create(width, height, Graphics::PixelFormat::createFormatCLUT8()); + _surface.create(width, height, Graphics::PixelFormat::createFormatCLUT8()); _freePixels = true; } -void Surface::blitFrom(const Graphics::Surface &src) { +void Surface::blitFrom(const Surface &src) { blitFrom(src, Common::Point(0, 0)); } @@ -56,23 +56,30 @@ void Surface::blitFrom(const ImageFrame &src) { blitFrom(src._frame, Common::Point(0, 0)); } -void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt) { - blitFrom(src, pt, Common::Rect(0, 0, src.w, src.h)); +void Surface::blitFrom(const Graphics::Surface &src) { + blitFrom(src, Common::Point(0, 0)); +} + +void Surface::blitFrom(const Surface &src, const Common::Point &pt) { + blitFrom(src, pt, Common::Rect(0, 0, src._surface.w, src._surface.h)); } void Surface::blitFrom(const ImageFrame &src, const Common::Point &pt) { blitFrom(src._frame, pt, Common::Rect(0, 0, src._frame.w, src._frame.h)); } -void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt, - const Common::Rect &srcBounds) { +void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt) { + blitFrom(src, pt, Common::Rect(0, 0, src.w, src.h)); +} + +void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds) { Common::Rect srcRect = srcBounds; Common::Rect destRect(pt.x, pt.y, pt.x + srcRect.width(), pt.y + srcRect.height()); if (srcRect.isValidRect() && clip(srcRect, destRect)) { // Surface is at least partially or completely on-screen addDirtyRect(destRect); - copyRectToSurface(src, destRect.left, destRect.top, srcRect); + _surface.copyRectToSurface(src, destRect.left, destRect.top, srcRect); } } @@ -80,6 +87,10 @@ void Surface::blitFrom(const ImageFrame &src, const Common::Point &pt, const Com blitFrom(src._frame, pt, srcBounds); } +void Surface::blitFrom(const Surface &src, const Common::Point &pt, const Common::Rect &srcBounds) { + blitFrom(src._surface, pt, srcBounds); +} + void Surface::transBlitFrom(const ImageFrame &src, const Common::Point &pt, bool flipped, int overrideColor) { transBlitFrom(src._frame, pt + src._offset, flipped, overrideColor); @@ -124,24 +135,24 @@ void Surface::fillRect(int x1, int y1, int x2, int y2, byte color) { } void Surface::fillRect(const Common::Rect &r, byte color) { - Graphics::Surface::fillRect(r, color); + _surface.fillRect(r, color); addDirtyRect(r); } bool Surface::clip(Common::Rect &srcBounds, Common::Rect &destBounds) { - if (destBounds.left >= this->w || destBounds.top >= this->h || - destBounds.right <= 0 || destBounds.bottom <= 0) + if (destBounds.left >= _surface.w || destBounds.top >= _surface.h || + destBounds.right <= 0 || destBounds.bottom <= 0) return false; // Clip the bounds if necessary to fit on-screen - if (destBounds.right > this->w) { - srcBounds.right -= destBounds.right - this->w; - destBounds.right = this->w; + if (destBounds.right > _surface.w) { + srcBounds.right -= destBounds.right - _surface.w; + destBounds.right = _surface.w; } - if (destBounds.bottom > this->h) { - srcBounds.bottom -= destBounds.bottom - this->h; - destBounds.bottom = this->h; + if (destBounds.bottom > _surface.h) { + srcBounds.bottom -= destBounds.bottom - _surface.h; + destBounds.bottom = _surface.h; } if (destBounds.top < 0) { @@ -158,7 +169,21 @@ bool Surface::clip(Common::Rect &srcBounds, Common::Rect &destBounds) { } void Surface::clear() { - fillRect(Common::Rect(0, 0, this->w, this->h), 0); + fillRect(Common::Rect(0, 0, _surface.w, _surface.h), 0); +} + +void Surface::free() { + if (_freePixels) { + _surface.free(); + _freePixels = false; + } +} + +void Surface::setPixels(byte *pixels, int w, int h) { + _surface.format = Graphics::PixelFormat::createFormatCLUT8(); + _surface.w = _surface.pitch = w; + _surface.h = h; + _surface.setPixels(pixels); } } // End of namespace Sherlock diff --git a/engines/sherlock/surface.h b/engines/sherlock/surface.h index 4b7166b090..f3b1b393bb 100644 --- a/engines/sherlock/surface.h +++ b/engines/sherlock/surface.h @@ -30,7 +30,7 @@ namespace Sherlock { struct ImageFrame; -class Surface : public Graphics::Surface { +class Surface { private: bool _freePixels; @@ -38,7 +38,30 @@ private: * Clips the given source bounds so the passed destBounds will be entirely on-screen */ bool clip(Common::Rect &srcBounds, Common::Rect &destBounds); + + /** + * Copy a surface into this one + */ + void blitFrom(const Graphics::Surface &src); + + /** + * Draws a surface at a given position within this surface + */ + void blitFrom(const Graphics::Surface &src, const Common::Point &pt); + + /** + * Draws a sub-section of a surface at a given position within this surface + */ + void blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds); + + /** + * Draws a surface at a given position within this surface with transparency + */ + void transBlitFrom(const Graphics::Surface &src, const Common::Point &pt, + bool flipped = false, int overrideColor = 0); protected: + Graphics::Surface _surface; + virtual void addDirtyRect(const Common::Rect &r) {} public: Surface(uint16 width, uint16 height); @@ -54,7 +77,7 @@ public: /** * Copy a surface into this one */ - void blitFrom(const Graphics::Surface &src); + void blitFrom(const Surface &src); /** * Copy an image frame into this surface @@ -64,7 +87,7 @@ public: /** * Draws a surface at a given position within this surface */ - void blitFrom(const Graphics::Surface &src, const Common::Point &pt); + void blitFrom(const Surface &src, const Common::Point &pt); /** * Copy an image frame onto this surface at a given position @@ -74,7 +97,7 @@ public: /** * Draws a sub-section of a surface at a given position within this surface */ - void blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds); + void blitFrom(const Surface &src, const Common::Point &pt, const Common::Rect &srcBounds); /** * Copy a sub-area of a source image frame into this surface at a given position @@ -88,9 +111,9 @@ public: bool flipped = false, int overrideColor = 0); /** - * Draws a surface at a given position within this surface with transparency - */ - void transBlitFrom(const Graphics::Surface &src, const Common::Point &pt, + * Draws a surface at a given position within this surface with transparency + */ + void transBlitFrom(const Surface &src, const Common::Point &pt, bool flipped = false, int overrideColor = 0); /** @@ -107,6 +130,25 @@ public: * Clear the screen */ void clear(); + + /** + * Free the underlying surface + */ + void free(); + + /** + * Set the pixels for the surface to an existing data block + */ + void setPixels(byte *pixels, int w, int h); + + inline uint16 w() const { return _surface.w; } + inline uint16 h() const { return _surface.h; } + inline const byte *getPixels() const { return (const byte *)_surface.getPixels(); } + inline byte *getPixels() { return (byte *)_surface.getPixels(); } + inline byte *getBasePtr(int x, int y) { return (byte *)_surface.getBasePtr(x, y); } + inline const byte *getBasePtr(int x, int y) const { return (const byte *)_surface.getBasePtr(x, y); } + inline void hLine(int x, int y, int x2, uint32 color) { _surface.hLine(x, y, x2, color); } + inline void vLine(int x, int y, int y2, uint32 color) { _surface.vLine(x, y, y2, color); } }; } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 861c1c695d..d36be4ed76 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -398,9 +398,9 @@ void UserInterface::depressButton(int num) { Screen &screen = *_vm->_screen; Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]); - Graphics::Surface &s = (*_controls)[num]._frame; - screen._backBuffer1.transBlitFrom(s, pt); - screen.slamArea(pt.x, pt.y, pt.x + s.w, pt.y + s.h); + ImageFrame &frame = (*_controls)[num]; + screen._backBuffer1.transBlitFrom(frame, pt); + screen.slamArea(pt.x, pt.y, pt.x + frame._width, pt.y + frame._height); } void UserInterface::restoreButton(int num) { @@ -451,10 +451,10 @@ void UserInterface::toggleButton(int num) { _keyboardInput = false; - Graphics::Surface &s = (*_controls)[num]._frame; + ImageFrame &frame = (*_controls)[num]; Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]); - screen._backBuffer1.transBlitFrom(s, pt); - screen.slamArea(pt.x, pt.y, pt.x + s.w, pt.y + s.h); + screen._backBuffer1.transBlitFrom(frame, pt); + screen.slamArea(pt.x, pt.y, pt.x + frame._width, pt.y + frame._height); } } else { _menuMode = STD_MODE; @@ -1220,7 +1220,7 @@ void UserInterface::doLookControl() { } else if (!_lookHelp) { // Need to close the window and depress the Look button Common::Point pt(MENU_POINTS[0][0], MENU_POINTS[0][1]); - screen._backBuffer2.blitFrom((*_controls)[0]._frame, pt); + screen._backBuffer2.blitFrom((*_controls)[0], pt); banishWindow(true); _windowBounds.top = CONTROLS_Y1; @@ -1801,8 +1801,8 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { Common::Point pt(MENU_POINTS[0][0], MENU_POINTS[0][1]); tempSurface.blitFrom(screen._backBuffer2, Common::Point(0, 0), - Common::Rect(pt.x, pt.y, pt.x + tempSurface.w, pt.y + tempSurface.h)); - screen._backBuffer2.transBlitFrom((*_controls)[0]._frame, pt); + Common::Rect(pt.x, pt.y, pt.x + tempSurface.w(), pt.y + tempSurface.h())); + screen._backBuffer2.transBlitFrom((*_controls)[0], pt); banishWindow(1); events.setCursor(MAGNIFY); @@ -1954,9 +1954,9 @@ void UserInterface::summonWindow(const Surface &bgSurface, bool slideUp) { if (slideUp) { // Gradually slide up the display of the window - for (int idx = 1; idx <= bgSurface.h; idx += 2) { + for (int idx = 1; idx <= bgSurface.h(); idx += 2) { screen._backBuffer->blitFrom(bgSurface, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - idx), - Common::Rect(0, 0, bgSurface.w, idx)); + Common::Rect(0, 0, bgSurface.w(), idx)); screen.slamRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - idx, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); @@ -1964,22 +1964,21 @@ void UserInterface::summonWindow(const Surface &bgSurface, bool slideUp) { } } else { // Gradually slide down the display of the window - for (int idx = 1; idx <= bgSurface.h; idx += 2) { + for (int idx = 1; idx <= bgSurface.h(); idx += 2) { screen._backBuffer->blitFrom(bgSurface, - Common::Point(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h), - Common::Rect(0, bgSurface.h - idx, bgSurface.w, bgSurface.h)); - screen.slamRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h, - SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT - bgSurface.h + idx)); + Common::Point(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h()), + Common::Rect(0, bgSurface.h() - idx, bgSurface.w(), bgSurface.h())); + screen.slamRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h(), + SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT - bgSurface.h() + idx)); events.delay(10); } } // Final display of the entire window - screen._backBuffer->blitFrom(bgSurface, Common::Point(0, - SHERLOCK_SCREEN_HEIGHT - bgSurface.h), - Common::Rect(0, 0, bgSurface.w, bgSurface.h)); - screen.slamArea(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h, bgSurface.w, bgSurface.h); + screen._backBuffer->blitFrom(bgSurface, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h()), + Common::Rect(0, 0, bgSurface.w(), bgSurface.h())); + screen.slamArea(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h(), bgSurface.w(), bgSurface.h()); _windowOpen = true; } -- cgit v1.2.3 From 06b39671e30ecd39585f2f7312af53abb9d27d1c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 19 May 2015 09:17:04 -0400 Subject: SHERLOCK: Further cleanup for SaveManager --- engines/sherlock/saveload.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index 63d3142262..5033a3b16d 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -38,7 +38,8 @@ const int ENV_POINTS[6][3] = { { 241, 280, 261 } // Quit }; -const char *const SAVEGAME_STR = "SHLK"; +static const char *const EMPTY_SAVEGAME_SLOT = "-EMPTY-"; +static const char *const SAVEGAME_STR = "SHLK"; #define SAVEGAME_STR_SIZE 4 #define ONSCREEN_FILES_COUNT 5 @@ -112,7 +113,7 @@ void SaveManager::createSavegameList() { _savegames.clear(); for (int idx = 0; idx < MAX_SAVEGAME_SLOTS; ++idx) - _savegames.push_back("-EMPTY-"); + _savegames.push_back(EMPTY_SAVEGAME_SLOT); SaveStateList saveList = getSavegameList(_target); for (uint idx = 0; idx < saveList.size(); ++idx) { @@ -401,7 +402,7 @@ bool SaveManager::promptForFilename(int slot) { screen.buttonPrint(Common::Point(ENV_POINTS[5][2], CONTROLS_Y), COMMAND_NULL, true, "Quit"); Common::String saveName = _savegames[slot]; - if (saveName.equalsIgnoreCase("-EMPTY-")) { + if (saveName.equalsIgnoreCase(EMPTY_SAVEGAME_SLOT)) { // It's an empty slot, so start off with an empty save name saveName = ""; @@ -445,17 +446,15 @@ bool SaveManager::promptForFilename(int slot) { xp -= screen.charWidth(saveName.lastChar()); screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_FOREGROUND); saveName.deleteLastChar(); - } - - if (keyState.keycode == Common::KEYCODE_RETURN) + + } else if (keyState.keycode == Common::KEYCODE_RETURN && saveName.compareToIgnoreCase(EMPTY_SAVEGAME_SLOT)) { done = 1; - if (keyState.keycode == Common::KEYCODE_ESCAPE) { + } else if (keyState.keycode == Common::KEYCODE_ESCAPE) { screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_BACKGROUND); done = -1; - } - - if (keyState.ascii >= ' ' && keyState.ascii <= 'z' && saveName.size() < 50 + + } else if (keyState.ascii >= ' ' && keyState.ascii <= 'z' && saveName.size() < 50 && (xp + screen.charWidth(keyState.ascii)) < 308) { char c = (char)keyState.ascii; -- cgit v1.2.3 From 033241eb434ff4916c140885a6cda84a593406d5 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 19 May 2015 09:19:42 -0400 Subject: SHERLOCK: Corrected incorrect method name in SaveManager --- engines/sherlock/saveload.cpp | 2 +- engines/sherlock/saveload.h | 4 ++-- engines/sherlock/user_interface.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index 5033a3b16d..3c8f3e4f60 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -386,7 +386,7 @@ bool SaveManager::checkGameOnScreen(int slot) { return false; } -bool SaveManager::promptForFilename(int slot) { +bool SaveManager::promptForDescription(int slot) { Events &events = *_vm->_events; Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; diff --git a/engines/sherlock/saveload.h b/engines/sherlock/saveload.h index 07626a2082..a86d5be035 100644 --- a/engines/sherlock/saveload.h +++ b/engines/sherlock/saveload.h @@ -131,9 +131,9 @@ public: bool checkGameOnScreen(int slot); /** - * Prompts the user to enter a filename in a given slot + * Prompts the user to enter a description in a given slot */ - bool promptForFilename(int slot); + bool promptForDescription(int slot); }; } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index d36be4ed76..7ac44ee99e 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -783,7 +783,7 @@ void UserInterface::doEnvControl() { if (saves.checkGameOnScreen(_selector)) _oldSelector = _selector; - if (saves.promptForFilename(_selector)) { + if (saves.promptForDescription(_selector)) { saves.saveGame(_selector + 1, saves._savegames[_selector]); banishWindow(1); @@ -954,7 +954,7 @@ void UserInterface::doEnvControl() { if (saves.checkGameOnScreen(_selector)) _oldSelector = _selector; - if (saves.promptForFilename(_selector)) { + if (saves.promptForDescription(_selector)) { saves.saveGame(_selector + 1, saves._savegames[_selector]); banishWindow(); _windowBounds.top = CONTROLS_Y1; -- cgit v1.2.3 From 6f9693102f99843501822f27431d839777fb43d5 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 19 May 2015 09:35:53 -0400 Subject: SHERLOCK: Further minor cleanups --- engines/sherlock/journal.cpp | 7 ++++--- engines/sherlock/saveload.cpp | 1 - engines/sherlock/saveload.h | 1 + engines/sherlock/user_interface.cpp | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 7afa60d396..f3754db95f 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -1114,13 +1114,14 @@ int Journal::getSearchString(bool printError) { xp -= screen.charWidth(name.lastChar()); screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), INV_FOREGROUND); name.deleteLastChar(); - } - - if (keyState.keycode == Common::KEYCODE_RETURN) { + + } else if (keyState.keycode == Common::KEYCODE_RETURN) { done = 1; + } else if (keyState.keycode == Common::KEYCODE_ESCAPE) { screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), BUTTON_MIDDLE); done = -1; + } else if (keyState.ascii >= ' ' && keyState.ascii <= 'z' && keyState.keycode != Common::KEYCODE_AT && name.size() < JOURNAL_SEACRH_MAX_CHARS && (xp + screen.charWidth(keyState.ascii)) < JOURNAL_SEARCH_RIGHT) { char ch = toupper(keyState.ascii); diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index 3c8f3e4f60..9848f8160f 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -41,7 +41,6 @@ const int ENV_POINTS[6][3] = { static const char *const EMPTY_SAVEGAME_SLOT = "-EMPTY-"; static const char *const SAVEGAME_STR = "SHLK"; #define SAVEGAME_STR_SIZE 4 -#define ONSCREEN_FILES_COUNT 5 /*----------------------------------------------------------------*/ diff --git a/engines/sherlock/saveload.h b/engines/sherlock/saveload.h index a86d5be035..066d983b26 100644 --- a/engines/sherlock/saveload.h +++ b/engines/sherlock/saveload.h @@ -33,6 +33,7 @@ namespace Sherlock { #define MAX_SAVEGAME_SLOTS 99 +#define ONSCREEN_FILES_COUNT 5 #define SHERLOCK_SAVEGAME_VERSION 1 enum SaveMode { SAVEMODE_NONE = 0, SAVEMODE_LOAD = 1, SAVEMODE_SAVE = 2 }; diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 7ac44ee99e..fbedbb9005 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -714,7 +714,7 @@ void UserInterface::doEnvControl() { // Handle selecting buttons, if any saves.highlightButtons(found); - if (found == 0 || found == 5) + if (found == 0 || found == ONSCREEN_FILES_COUNT) saves._envMode = SAVEMODE_NONE; } -- cgit v1.2.3 From 4849e008977d87b707d70c836c7abcd0c79eb9de Mon Sep 17 00:00:00 2001 From: Strangerke Date: Tue, 19 May 2015 19:06:44 +0200 Subject: SHERLOCK: Fix some issues pointed by eriktorbjorn --- engines/sherlock/surface.cpp | 6 +++--- engines/sherlock/surface.h | 2 +- engines/sherlock/user_interface.cpp | 18 ++++++++---------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/engines/sherlock/surface.cpp b/engines/sherlock/surface.cpp index 9214a75ded..80495a398c 100644 --- a/engines/sherlock/surface.cpp +++ b/engines/sherlock/surface.cpp @@ -179,10 +179,10 @@ void Surface::free() { } } -void Surface::setPixels(byte *pixels, int w, int h) { +void Surface::setPixels(byte *pixels, int width, int height) { _surface.format = Graphics::PixelFormat::createFormatCLUT8(); - _surface.w = _surface.pitch = w; - _surface.h = h; + _surface.w = _surface.pitch = width; + _surface.h = height; _surface.setPixels(pixels); } diff --git a/engines/sherlock/surface.h b/engines/sherlock/surface.h index f3b1b393bb..1cb78db072 100644 --- a/engines/sherlock/surface.h +++ b/engines/sherlock/surface.h @@ -139,7 +139,7 @@ public: /** * Set the pixels for the surface to an existing data block */ - void setPixels(byte *pixels, int w, int h); + void setPixels(byte *pixels, int width, int height); inline uint16 w() const { return _surface.w; } inline uint16 h() const { return _surface.h; } diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index fbedbb9005..e1d6619ed7 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -523,7 +523,7 @@ void UserInterface::examine() { } if (_invLookFlag) { - // Dont close the inventory window when starting an examine display, since it's + // Don't close the inventory window when starting an examine display, since its // window will slide up to replace the inventory display _windowOpen = false; _menuMode = LOOK_MODE; @@ -690,13 +690,11 @@ void UserInterface::doEnvControl() { _keyboardInput = false; int found = saves.getHighlightedButton(); - if (events._pressed || events._released) - { + if (events._pressed || events._released) { events.clearKeyboard(); // Check for a filename entry being highlighted - if ((events._pressed || events._released) && mousePos.y > (CONTROLS_Y + 10)) - { + if ((events._pressed || events._released) && mousePos.y > (CONTROLS_Y + 10)) { int found1 = 0; for (_selector = 0; (_selector < 5) && !found1; ++_selector) if (mousePos.y > (CONTROLS_Y + 11 + _selector * 10) && mousePos.y < (CONTROLS_Y + 21 + _selector * 10)) @@ -828,7 +826,7 @@ void UserInterface::doEnvControl() { color = (saves._savegameIndex == MAX_SAVEGAME_SLOTS - 5) ? COMMAND_NULL : COMMAND_FOREGROUND; screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), color, true, "Down"); - // Check for there are more pending U keys pressed + // Check whether there are more pending U keys pressed moreKeys = false; if (events.kbHit()) { Common::KeyState keyState = events.getKey(); @@ -864,7 +862,7 @@ void UserInterface::doEnvControl() { color = (saves._savegameIndex == MAX_SAVEGAME_SLOTS - 5) ? COMMAND_NULL : COMMAND_FOREGROUND; screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), color, true, "Down"); - // Check for there are more pending D keys pressed + // Check whether there are more pending D keys pressed moreKeys = false; if (events.kbHit()) { Common::KeyState keyState; @@ -950,7 +948,7 @@ void UserInterface::doEnvControl() { if (saves._envMode == SAVEMODE_LOAD) { saves.loadGame(_selector + 1); } else if (saves._envMode == SAVEMODE_SAVE || _selector == MAX_SAVEGAME_SLOTS) { - // We're alreaady in save mode, or pointed to an empty save slot + // We're already in save mode, or pointing to an empty save slot if (saves.checkGameOnScreen(_selector)) _oldSelector = _selector; @@ -1007,7 +1005,7 @@ void UserInterface::doInvControl() { events.clearKeyboard(); if (found != -1) - // If a slot highlighted, set it's color + // If a slot highlighted, set its color colors[found] = COMMAND_HIGHLIGHTED; screen.buttonPrint(Common::Point(INVENTORY_POINTS[0][2], CONTROLS_Y1), colors[0], true, "Exit"); @@ -1135,7 +1133,7 @@ void UserInterface::doInvControl() { inv.putInv(SLAM_DISPLAY); inv.invCommands(true); } else { - // If something is being given, make sure it's to a person + // If something is being given, make sure it's being given to a person if (inv._invMode == 3) { if (_bgFound != -1 && scene._bgShapes[_bgFound]._aType == PERSON) _find = _bgFound; -- cgit v1.2.3 From 85081b7702e7571a144ff57accd5ac9123f4123f Mon Sep 17 00:00:00 2001 From: Strangerke Date: Tue, 19 May 2015 19:37:33 +0200 Subject: SHERLOCK: Systematically use InvMode values when it's appropriate --- engines/sherlock/inventory.cpp | 18 +++++++++--------- engines/sherlock/user_interface.cpp | 31 ++++++++++++++++--------------- engines/sherlock/user_interface.h | 2 +- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index 63642f4e5a..265b12ce76 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -250,16 +250,16 @@ void Inventory::invCommands(bool slamIt) { if (slamIt) { screen.buttonPrint(Common::Point(INVENTORY_POINTS[0][2], CONTROLS_Y1), - _invMode == 0 ? COMMAND_HIGHLIGHTED :COMMAND_FOREGROUND, + _invMode == INVMODE_EXIT ? COMMAND_HIGHLIGHTED :COMMAND_FOREGROUND, true, "Exit"); screen.buttonPrint(Common::Point(INVENTORY_POINTS[1][2], CONTROLS_Y1), - _invMode == 1 ? COMMAND_HIGHLIGHTED :COMMAND_FOREGROUND, + _invMode == INVMODE_LOOK ? COMMAND_HIGHLIGHTED :COMMAND_FOREGROUND, true, "Look"); screen.buttonPrint(Common::Point(INVENTORY_POINTS[2][2], CONTROLS_Y1), - _invMode == 2 ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, + _invMode == INVMODE_USE ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, true, "Use"); screen.buttonPrint(Common::Point(INVENTORY_POINTS[3][2], CONTROLS_Y1), - _invMode == 3 ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, + _invMode == INVMODE_GIVE ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, true, "Give"); screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1), _invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND, @@ -273,20 +273,20 @@ void Inventory::invCommands(bool slamIt) { screen.print(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1 + 1), (_holdings - _invIndex <= 6) ? COMMAND_NULL : COMMAND_FOREGROUND, "__"); - if (_invMode != 1) + if (_invMode != INVMODE_LOOK) ui.clearInfo(); } else { screen.buttonPrint(Common::Point(INVENTORY_POINTS[0][2], CONTROLS_Y1), - _invMode == 0 ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, + _invMode == INVMODE_EXIT ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, false, "Exit"); screen.buttonPrint(Common::Point(INVENTORY_POINTS[1][2], CONTROLS_Y1), - _invMode == 1 ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, + _invMode == INVMODE_LOOK ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, false, "Look"); screen.buttonPrint(Common::Point(INVENTORY_POINTS[2][2], CONTROLS_Y1), - _invMode == 2 ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, + _invMode == INVMODE_USE ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, false, "Use"); screen.buttonPrint(Common::Point(INVENTORY_POINTS[3][2], CONTROLS_Y1), - _invMode == 3 ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, + _invMode == INVMODE_GIVE ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND, false, "Give"); screen.gPrint(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1), _invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND, diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index e1d6619ed7..943d3498b2 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -300,7 +300,7 @@ void UserInterface::handleInput() { case USE_MODE: case GIVE_MODE: case INV_MODE: - if (inv._invMode == 1 || inv._invMode == 2 || inv._invMode == 3) { + if (inv._invMode == INVMODE_LOOK || inv._invMode == INVMODE_USE || inv._invMode == INVMODE_GIVE) { if (pt.y > CONTROLS_Y) lookInv(); else @@ -568,10 +568,10 @@ void UserInterface::lookScreen(const Common::Point &pt) { if (!tempStr.empty() && tempStr[0] != ' ') { // If inventory is active and an item is selected for a Use or Give action if ((_menuMode == INV_MODE || _menuMode == USE_MODE || _menuMode == GIVE_MODE) && - (inv._invMode == 2 || inv._invMode == 3)) { + (inv._invMode == INVMODE_USE || inv._invMode == INVMODE_GIVE)) { int width1 = 0, width2 = 0; int x, width; - if (inv._invMode == 2) { + if (inv._invMode == INVMODE_USE) { // Using an object x = width = screen.stringWidth("Use "); @@ -1028,7 +1028,7 @@ void UserInterface::doInvControl() { } bool flag = false; - if (inv._invMode == 1 || inv._invMode == 2 || inv._invMode == 3) { + if (inv._invMode == INVMODE_LOOK || inv._invMode == INVMODE_USE || inv._invMode == INVMODE_GIVE) { Common::Rect r(15, CONTROLS_Y1 + 11, 314, SHERLOCK_SCREEN_HEIGHT - 2); if (r.contains(mousePos)) { _selector = (mousePos.x - 6) / 52 + inv._invIndex; @@ -1050,13 +1050,13 @@ void UserInterface::doInvControl() { if (_key == 'E' || _key == 'L' || _key == 'U' || _key == 'G' || _key == '-' || _key == '+') { - int temp = inv._invMode; + InvMode temp = inv._invMode; const char *chP = strchr(INVENTORY_COMMANDS, _key); inv._invMode = !chP ? INVMODE_INVALID : (InvMode)(chP - INVENTORY_COMMANDS); inv.invCommands(true); - inv._invMode = (InvMode)temp; + inv._invMode = temp; _keyboardInput = true; if (_key == 'E') inv._invMode = INVMODE_EXIT; @@ -1134,7 +1134,7 @@ void UserInterface::doInvControl() { inv.invCommands(true); } else { // If something is being given, make sure it's being given to a person - if (inv._invMode == 3) { + if (inv._invMode == INVMODE_GIVE) { if (_bgFound != -1 && scene._bgShapes[_bgFound]._aType == PERSON) _find = _bgFound; else @@ -1143,7 +1143,7 @@ void UserInterface::doInvControl() { _find = _bgFound; } - if ((mousePos.y < CONTROLS_Y1) && (inv._invMode == 1) && (_find >= 0) && (_find < 1000)) { + if ((mousePos.y < CONTROLS_Y1) && (inv._invMode == INVMODE_LOOK) && (_find >= 0) && (_find < 1000)) { if (!scene._bgShapes[_find]._examine.empty() && scene._bgShapes[_find]._examine[0] >= ' ') inv.refreshInv(); @@ -1166,17 +1166,17 @@ void UserInterface::doInvControl() { // is being tried on an object in the scene without an inventory // object being highlighted first. - if ((inv._invMode == 2 || (_selector != -1 && inv._invMode == 3)) && _find >= 0) { + if ((inv._invMode == INVMODE_USE || (_selector != -1 && inv._invMode == INVMODE_GIVE)) && _find >= 0) { events._pressed = events._released = false; _infoFlag = true; clearInfo(); - int temp = _selector; // Save the selector + int tempSel = _selector; // Save the selector _selector = -1; inv.putInv(SLAM_DISPLAY); - _selector = temp; // Restore it - temp = inv._invMode; + _selector = tempSel; // Restore it + InvMode tempMode = inv._invMode; inv._invMode = INVMODE_USE55; inv.invCommands(true); @@ -1187,12 +1187,13 @@ void UserInterface::doInvControl() { inv.freeInv(); + bool giveFl = (tempMode >= INVMODE_GIVE); if (_selector >= 0) // Use/Give inv object with scene object - checkUseAction(&scene._bgShapes[_find]._use[0], inv[_selector]._name, MUSE, _find, temp - 2); + checkUseAction(&scene._bgShapes[_find]._use[0], inv[_selector]._name, MUSE, _find, giveFl); else // Now inv object has been highlighted - checkUseAction(&scene._bgShapes[_find]._use[0], "*SELF*", MUSE, _find, temp - 2); + checkUseAction(&scene._bgShapes[_find]._use[0], "*SELF*", MUSE, _find, giveFl); _selector = _oldSelector = -1; } @@ -2065,7 +2066,7 @@ void UserInterface::banishWindow(bool slideUp) { } void UserInterface::checkUseAction(const UseType *use, const Common::String &invName, - const char *const messages[], int objNum, int giveMode) { + const char *const messages[], int objNum, bool giveMode) { Events &events = *_vm->_events; Inventory &inv = *_vm->_inventory; Scene &scene = *_vm->_scene; diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index 068d1eaa99..9fe69cde18 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -172,7 +172,7 @@ private: * Checks to see whether a USE action is valid on the given object */ void checkUseAction(const UseType *use, const Common::String &invName, const char *const messages[], - int objNum, int giveMode); + int objNum, bool giveMode); /** * Called for OPEN, CLOSE, and MOVE actions are being done -- cgit v1.2.3 From 456e0c584f2497b82b6be5f531f655b9681a11b8 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Tue, 19 May 2015 20:07:24 +0200 Subject: SHERLOCK: Use a bit more MenuMode and SaveMode --- engines/sherlock/saveload.cpp | 4 ++-- engines/sherlock/scene.cpp | 2 +- engines/sherlock/screen.h | 32 ++++++++++++++++---------------- engines/sherlock/talk.cpp | 7 +++++-- engines/sherlock/user_interface.cpp | 8 ++++---- 5 files changed, 28 insertions(+), 25 deletions(-) diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index 9848f8160f..c13d6dd9ee 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -260,12 +260,12 @@ void SaveManager::highlightButtons(int btnIndex) { screen.buttonPrint(Common::Point(ENV_POINTS[0][2], CONTROLS_Y), color, 1, "Exit"); - if ((btnIndex == 1) || ((_envMode == 1) && (btnIndex != 2))) + if ((btnIndex == 1) || ((_envMode == SAVEMODE_LOAD) && (btnIndex != 2))) screen.buttonPrint(Common::Point(ENV_POINTS[1][2], CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Load"); else screen.buttonPrint(Common::Point(ENV_POINTS[1][2], CONTROLS_Y), COMMAND_FOREGROUND, true, "Load"); - if ((btnIndex == 2) || ((_envMode == 2) && (btnIndex != 1))) + if ((btnIndex == 2) || ((_envMode == SAVEMODE_SAVE) && (btnIndex != 1))) screen.buttonPrint(Common::Point(ENV_POINTS[2][2], CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Save"); else screen.buttonPrint(Common::Point(ENV_POINTS[2][2], CONTROLS_Y), COMMAND_FOREGROUND, true, "Save"); diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index d835b5caa8..573dfff2b1 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -150,7 +150,7 @@ void Scene::selectScene() { loadScene(sceneFile); - // If the fade style was changed from running amovie, then reset it + // If the fade style was changed from running a movie, then reset it if (_tempFadeStyle) { screen._fadeStyle = _tempFadeStyle; _tempFadeStyle = 0; diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 0369422bc3..ee9e800cdc 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -36,22 +36,22 @@ namespace Sherlock { #define VGA_COLOR_TRANS(x) ((x) * 255 / 63) enum { - INFO_BLACK = 1, - INFO_FOREGROUND = 11, - INFO_BACKGROUND = 1, - BORDER_COLOR = 237, - INV_FOREGROUND = 14, - INV_BACKGROUND = 1, - COMMAND_HIGHLIGHTED = 10, - COMMAND_FOREGROUND = 15, - COMMAND_BACKGROUND = 4, - COMMAND_NULL = 248, - BUTTON_TOP = 233, - BUTTON_MIDDLE = 244, - BUTTON_BOTTOM = 248, - TALK_FOREGROUND = 12, - TALK_NULL = 16, - PEN_COLOR = 250 + INFO_BLACK = 1, + INFO_FOREGROUND = 11, + INFO_BACKGROUND = 1, + BORDER_COLOR = 237, + INV_FOREGROUND = 14, + INV_BACKGROUND = 1, + COMMAND_HIGHLIGHTED = 10, + COMMAND_FOREGROUND = 15, + COMMAND_BACKGROUND = 4, + COMMAND_NULL = 248, + BUTTON_TOP = 233, + BUTTON_MIDDLE = 244, + BUTTON_BOTTOM = 248, + TALK_FOREGROUND = 12, + TALK_NULL = 16, + PEN_COLOR = 250 }; class SherlockEngine; diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 734aa76e0a..47b9f6f277 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -146,7 +146,7 @@ void Talk::talkTo(const Common::String &filename) { } // Save the ui mode temporarily and switch to talk mode - int savedMode = ui._menuMode; + MenuMode savedMode = ui._menuMode; ui._menuMode = TALK_MODE; // Turn on the Exit option @@ -183,7 +183,7 @@ void Talk::talkTo(const Common::String &filename) { // Restore any pressed button if (!ui._windowOpen && savedMode != STD_MODE) - ui.restoreButton(savedMode - 1); + ui.restoreButton((int)(savedMode - 1)); // Clear the ui counter so that anything displayed on the info line // before the window was opened isn't cleared @@ -258,6 +258,9 @@ void Talk::talkTo(const Common::String &filename) { events._pressed = events._released = events._oldButtons = 0; abortFlag = true; break; + + default: + break; } } diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 943d3498b2..c42829167b 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -389,7 +389,7 @@ void UserInterface::handleInput() { doMainControl(); } - if (pt.y < CONTROLS_Y && events._pressed && _oldTemp != (_menuMode - 1) && _oldKey != -1) + if (pt.y < CONTROLS_Y && events._pressed && _oldTemp != (int)(_menuMode - 1) && _oldKey != -1) restoreButton(_oldTemp); } } @@ -438,7 +438,7 @@ void UserInterface::pushButton(int num) { void UserInterface::toggleButton(int num) { Screen &screen = *_vm->_screen; - if (_menuMode != (num + 1)) { + if (_menuMode != (MenuMode)(num + 1)) { _menuMode = (MenuMode)(num + 1); _oldKey = COMMANDS[num]; _oldTemp = num; @@ -700,7 +700,7 @@ void UserInterface::doEnvControl() { if (mousePos.y > (CONTROLS_Y + 11 + _selector * 10) && mousePos.y < (CONTROLS_Y + 21 + _selector * 10)) found1 = 1; - if (_selector + saves._savegameIndex - 1 < MAX_SAVEGAME_SLOTS + (saves._envMode != 1)) + if (_selector + saves._savegameIndex - 1 < MAX_SAVEGAME_SLOTS + (saves._envMode != SAVEMODE_LOAD)) _selector = _selector + saves._savegameIndex - 1; else _selector = -1; @@ -734,7 +734,7 @@ void UserInterface::doEnvControl() { } else if (_key >= '1' && _key <= '9') { _keyboardInput = true; _selector = _key - '1'; - if (_selector >= MAX_SAVEGAME_SLOTS + (saves._envMode == 1 ? 0 : 1)) + if (_selector >= MAX_SAVEGAME_SLOTS + (saves._envMode == SAVEMODE_LOAD ? 0 : 1)) _selector = -1; if (saves.checkGameOnScreen(_selector)) -- cgit v1.2.3 From 20d859377df416cee0da460d1bac600df09058bb Mon Sep 17 00:00:00 2001 From: Strangerke Date: Tue, 19 May 2015 22:30:47 +0200 Subject: SHERLOCK: Trim useless spaces and tabs --- engines/sherlock/detection.cpp | 2 +- engines/sherlock/journal.cpp | 18 +++++++++--------- engines/sherlock/scalpel/darts.cpp | 8 +++----- engines/sherlock/scalpel/scalpel.h | 4 ++-- engines/sherlock/scene.cpp | 8 ++++---- 5 files changed, 19 insertions(+), 21 deletions(-) diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp index da3ad4628f..ea68d79a1b 100644 --- a/engines/sherlock/detection.cpp +++ b/engines/sherlock/detection.cpp @@ -118,7 +118,7 @@ static const ADExtraGuiOptionsMap optionsList[] = { class SherlockMetaEngine : public AdvancedMetaEngine { public: - SherlockMetaEngine() : AdvancedMetaEngine(Sherlock::gameDescriptions, sizeof(Sherlock::SherlockGameDescription), + SherlockMetaEngine() : AdvancedMetaEngine(Sherlock::gameDescriptions, sizeof(Sherlock::SherlockGameDescription), sherlockGames, optionsList) {} virtual const char *getName() const { diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index f3754db95f..ba6a809b44 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -496,7 +496,7 @@ void Journal::drawJournalFrame() { screen.makeButton(Common::Rect(JOURNAL_POINTS[8][0], JOURNAL_BUTTONS_Y + 11, JOURNAL_POINTS[8][1], JOURNAL_BUTTONS_Y + 21), JOURNAL_POINTS[8][2] - screen.stringWidth("Print Text") / 2, "Print Text"); - screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11), + screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11), COMMAND_NULL, false, "Print Text"); } @@ -918,7 +918,7 @@ bool Journal::handleEvents(int key) { drawJournal(1, LINES_PER_PAGE); doArrows(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); - + } else if (((btn == BTN_DOWN && events._released) || key == 'D') && _down) { // Scroll down drawJournal(2, LINES_PER_PAGE); @@ -934,7 +934,7 @@ bool Journal::handleEvents(int key) { doArrows(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); - + } else if (((btn == BTN_SEARCH && events._released) || key == 'S') && !_journal.empty()) { screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), COMMAND_FOREGROUND, true, "Search"); bool notFound = false; @@ -965,7 +965,7 @@ bool Journal::handleEvents(int key) { } } while (!doneFlag); doneFlag = false; - + } else if (((btn == BTN_FIRST_PAGE && events._released) || key == 'F') && _up) { // First page _index = _sub = 0; @@ -976,7 +976,7 @@ bool Journal::handleEvents(int key) { drawJournal(0, 0); doArrows(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); - + } else if (((btn == BTN_LAST_PAGE && events._released) || key == 'L') && _down) { // Last page if ((_page + 10) > _maxPage) @@ -1114,15 +1114,15 @@ int Journal::getSearchString(bool printError) { xp -= screen.charWidth(name.lastChar()); screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), INV_FOREGROUND); name.deleteLastChar(); - + } else if (keyState.keycode == Common::KEYCODE_RETURN) { done = 1; - + } else if (keyState.keycode == Common::KEYCODE_ESCAPE) { screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), BUTTON_MIDDLE); done = -1; - - } else if (keyState.ascii >= ' ' && keyState.ascii <= 'z' && keyState.keycode != Common::KEYCODE_AT && + + } else if (keyState.ascii >= ' ' && keyState.ascii <= 'z' && keyState.keycode != Common::KEYCODE_AT && name.size() < JOURNAL_SEACRH_MAX_CHARS && (xp + screen.charWidth(keyState.ascii)) < JOURNAL_SEARCH_RIGHT) { char ch = toupper(keyState.ascii); screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), BUTTON_MIDDLE); diff --git a/engines/sherlock/scalpel/darts.cpp b/engines/sherlock/scalpel/darts.cpp index 23ca95454f..96d272fed0 100644 --- a/engines/sherlock/scalpel/darts.cpp +++ b/engines/sherlock/scalpel/darts.cpp @@ -413,11 +413,9 @@ int Darts::doPowerBar(const Common::Point &pt, byte color, int goToPower, bool i if (sound._musicOn) { if (!(idx % 3)) sound.waitTimerRoland(1); - } else { - if (!(idx % 8)) - events.wait(1); - } - + } else if (!(idx % 8)) + events.wait(1); + ++idx; } while (!done); diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h index 14e30ff996..8743bfb7a9 100644 --- a/engines/sherlock/scalpel/scalpel.h +++ b/engines/sherlock/scalpel/scalpel.h @@ -31,9 +31,9 @@ namespace Sherlock { namespace Scalpel { enum { BLACKWOOD_CAPTURE = 2, BAKER_STREET = 4, DRAWING_ROOM = 12, STATION = 17, PUB_INTERIOR = 19, - LAWYER_OFFICE = 27, BAKER_ST_EXTERIOR = 39, RESCUE_ANNA = 52, MOOREHEAD_DEATH = 53, EXIT_GAME = 55, + LAWYER_OFFICE = 27, BAKER_ST_EXTERIOR = 39, RESCUE_ANNA = 52, MOOREHEAD_DEATH = 53, EXIT_GAME = 55, BRUMWELL_SUICIDE = 70, OVERHEAD_MAP2 = 98, DARTS_GAME = 99, OVERHEAD_MAP = 100 }; - + class ScalpelEngine : public SherlockEngine { private: Darts *_darts; diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 573dfff2b1..f97b791724 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -262,7 +262,7 @@ bool Scene::loadScene(const Common::String &filename) { } } else { Common::SeekableReadStream *infoStream; - + // Read shapes infoStream = Resources::decompressLZ(*rrmStream, bgHeader._numStructs * 569); @@ -271,7 +271,7 @@ bool Scene::loadScene(const Common::String &filename) { _bgShapes[idx].load(*infoStream); delete infoStream; - + // Read description texts if (bgHeader._descSize) { infoStream = Resources::decompressLZ(*rrmStream, bgHeader._descSize); @@ -764,7 +764,7 @@ void Scene::updateBackground() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { if ((_bgShapes[idx]._type == ACTIVE_BG_SHAPE || _bgShapes[idx]._type == STATIC_BG_SHAPE) && _bgShapes[idx]._misc == NORMAL_FORWARD) - screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, + screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & OBJ_FLIPPED); } @@ -784,7 +784,7 @@ void Scene::updateBackground() { if ((_bgShapes[idx]._type == ACTIVE_BG_SHAPE || _bgShapes[idx]._type == STATIC_BG_SHAPE) && _bgShapes[idx]._misc == FORWARD) - screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, + screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & OBJ_FLIPPED); } -- cgit v1.2.3 From 9c56d616b0031980011cd0e685082d8782b36bc2 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 19 May 2015 19:08:48 -0400 Subject: SHERLOCK: Fix regression in intro sequence display --- engines/sherlock/animation.cpp | 2 +- engines/sherlock/surface.h | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 7c1f2cd229..21d63633d3 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -88,7 +88,7 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade, // Draw the sprite. Note that we explicitly use the raw frame below, rather than the ImageFrame, // since we don't want the offsets in the image file to be used, just the explicit position we specify - screen.transBlitFrom(images[imageFrame], pt); + screen.transBlitFrom(images[imageFrame]._frame, pt); } else { // At this point, either the sprites for the frame has been complete, or there weren't any sprites // at all to draw for the frame diff --git a/engines/sherlock/surface.h b/engines/sherlock/surface.h index 1cb78db072..ccabf02a23 100644 --- a/engines/sherlock/surface.h +++ b/engines/sherlock/surface.h @@ -53,12 +53,6 @@ private: * Draws a sub-section of a surface at a given position within this surface */ void blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds); - - /** - * Draws a surface at a given position within this surface with transparency - */ - void transBlitFrom(const Graphics::Surface &src, const Common::Point &pt, - bool flipped = false, int overrideColor = 0); protected: Graphics::Surface _surface; @@ -116,6 +110,12 @@ public: void transBlitFrom(const Surface &src, const Common::Point &pt, bool flipped = false, int overrideColor = 0); + /** + * Draws a surface at a given position within this surface with transparency + */ + void transBlitFrom(const Graphics::Surface &src, const Common::Point &pt, + bool flipped = false, int overrideColor = 0); + /** * Fill a given area of the surface with a given color */ -- cgit v1.2.3 From de08eb071e37013627dd4de941a50b8e45441c71 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 19 May 2015 19:11:57 -0400 Subject: SHERLOCK: Use more constants in doEnvControl --- engines/sherlock/user_interface.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index c42829167b..8121eee7bc 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -696,7 +696,7 @@ void UserInterface::doEnvControl() { // Check for a filename entry being highlighted if ((events._pressed || events._released) && mousePos.y > (CONTROLS_Y + 10)) { int found1 = 0; - for (_selector = 0; (_selector < 5) && !found1; ++_selector) + for (_selector = 0; (_selector < ONSCREEN_FILES_COUNT) && !found1; ++_selector) if (mousePos.y > (CONTROLS_Y + 11 + _selector * 10) && mousePos.y < (CONTROLS_Y + 21 + _selector * 10)) found1 = 1; @@ -746,7 +746,7 @@ void UserInterface::doEnvControl() { } if (_selector != _oldSelector) { - if (_oldSelector != -1 && _oldSelector >= saves._savegameIndex && _oldSelector < (saves._savegameIndex + 5)) { + if (_oldSelector != -1 && _oldSelector >= saves._savegameIndex && _oldSelector < (saves._savegameIndex + ONSCREEN_FILES_COUNT)) { screen.print(Common::Point(6, CONTROLS_Y + 12 + (_oldSelector - saves._savegameIndex) * 10), INV_FOREGROUND, "%d.", _oldSelector + 1); screen.print(Common::Point(24, CONTROLS_Y + 12 + (_oldSelector - saves._savegameIndex) * 10), @@ -810,9 +810,9 @@ void UserInterface::doEnvControl() { screen._backBuffer1.fillRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT - 1), INV_BACKGROUND); - for (int idx = saves._savegameIndex; idx < (saves._savegameIndex + 5); ++idx) { + for (int idx = saves._savegameIndex; idx < (saves._savegameIndex + ONSCREEN_FILES_COUNT); ++idx) { color = INV_FOREGROUND; - if (idx == _selector && idx >= saves._savegameIndex && idx < (saves._savegameIndex + 5)) + if (idx == _selector && idx >= saves._savegameIndex && idx < (saves._savegameIndex + ONSCREEN_FILES_COUNT)) color = TALK_FOREGROUND; screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, "%d.", idx + 1); @@ -823,7 +823,7 @@ void UserInterface::doEnvControl() { color = !saves._savegameIndex ? COMMAND_NULL : COMMAND_FOREGROUND; screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), color, true, "Up"); - color = (saves._savegameIndex == MAX_SAVEGAME_SLOTS - 5) ? COMMAND_NULL : COMMAND_FOREGROUND; + color = (saves._savegameIndex == MAX_SAVEGAME_SLOTS - ONSCREEN_FILES_COUNT) ? COMMAND_NULL : COMMAND_FOREGROUND; screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), color, true, "Down"); // Check whether there are more pending U keys pressed @@ -835,15 +835,15 @@ void UserInterface::doEnvControl() { moreKeys = _key == 'U'; } } while ((saves._savegameIndex) && moreKeys); - } else if (((found == 4 && events._released) || _key == 'D') && saves._savegameIndex < (MAX_SAVEGAME_SLOTS - 5)) { + } else if (((found == 4 && events._released) || _key == 'D') && saves._savegameIndex < (MAX_SAVEGAME_SLOTS - ONSCREEN_FILES_COUNT)) { bool moreKeys; do { saves._savegameIndex++; screen._backBuffer1.fillRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT - 1), INV_BACKGROUND); - for (int idx = saves._savegameIndex; idx < (saves._savegameIndex + 5); ++idx) { - if (idx == _selector && idx >= saves._savegameIndex && idx < (saves._savegameIndex + 5)) + for (int idx = saves._savegameIndex; idx < (saves._savegameIndex + ONSCREEN_FILES_COUNT); ++idx) { + if (idx == _selector && idx >= saves._savegameIndex && idx < (saves._savegameIndex + ONSCREEN_FILES_COUNT)) color = TALK_FOREGROUND; else color = INV_FOREGROUND; @@ -859,7 +859,7 @@ void UserInterface::doEnvControl() { color = (!saves._savegameIndex) ? COMMAND_NULL : COMMAND_FOREGROUND; screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), color, true, "Up"); - color = (saves._savegameIndex == MAX_SAVEGAME_SLOTS - 5) ? COMMAND_NULL : COMMAND_FOREGROUND; + color = (saves._savegameIndex == MAX_SAVEGAME_SLOTS - ONSCREEN_FILES_COUNT) ? COMMAND_NULL : COMMAND_FOREGROUND; screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), color, true, "Down"); // Check whether there are more pending D keys pressed @@ -870,8 +870,8 @@ void UserInterface::doEnvControl() { moreKeys = _key == 'D'; } - } while (saves._savegameIndex < (MAX_SAVEGAME_SLOTS - 5) && moreKeys); - } else if ((found == 5 && events._released) || _key == 'Q') { + } while (saves._savegameIndex < (MAX_SAVEGAME_SLOTS - ONSCREEN_FILES_COUNT) && moreKeys); + } else if ((found == ONSCREEN_FILES_COUNT && events._released) || _key == 'Q') { clearWindow(); screen.print(Common::Point(0, CONTROLS_Y + 20), INV_FOREGROUND, "Are you sure you wish to Quit ?"); screen.vgaBar(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y + 10), BORDER_COLOR); -- cgit v1.2.3 From ed7dd6823f878238b86f1006ab438588751b6634 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Wed, 20 May 2015 07:12:56 +0200 Subject: SHERLOCK: Add missing game type in detection --- engines/sherlock/detection_tables.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/detection_tables.h b/engines/sherlock/detection_tables.h index a13231d3fc..9315fa1bdd 100644 --- a/engines/sherlock/detection_tables.h +++ b/engines/sherlock/detection_tables.h @@ -80,7 +80,8 @@ static const SherlockGameDescription gameDescriptions[] = { Common::kPlatformDOS, ADGF_UNSTABLE, GUIO0() - } + }, + GType_RoseTattoo }, { -- cgit v1.2.3 From fe8139b57168bbb85eb1d4bb0d2c62219ee6383d Mon Sep 17 00:00:00 2001 From: Strangerke Date: Wed, 20 May 2015 07:13:18 +0200 Subject: SHERLOCK: Improve comment as suggested by LordHoto --- engines/sherlock/user_interface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 8121eee7bc..ed6558c6dd 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1159,7 +1159,7 @@ void UserInterface::doInvControl() { if (talk._talkToAbort) return; - // Now check for the Use and Give actions. If inv_mode is 3, + // Now check for the Use and Give actions. If inv_mode is INVMODE_GIVE, // that means GIVE is in effect, _selector is the object being // given, and _find is the target. // The same applies to USE, except if _selector is -1, then USE -- cgit v1.2.3 From 30133cef0e2a840325c1b46b106628c3cccd7d04 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 20 May 2015 08:28:12 -0400 Subject: SHERLOCK: Re-add GCC_PRINTF and fix resulting GCC warnings --- engines/sherlock/journal.cpp | 20 ++++++++++---------- engines/sherlock/map.cpp | 6 +++--- engines/sherlock/objects.cpp | 6 +++--- engines/sherlock/scalpel/darts.cpp | 4 ++-- engines/sherlock/screen.cpp | 8 ++++---- engines/sherlock/screen.h | 4 ++-- engines/sherlock/talk.cpp | 26 +++++++++++++------------- engines/sherlock/user_interface.cpp | 22 +++++++++++----------- 8 files changed, 48 insertions(+), 48 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index ba6a809b44..5a8338bdc8 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -732,26 +732,26 @@ bool Journal::drawJournal(int direction, int howFar) { screen.gPrint(Common::Point(53, yp), 15, "%s", lineStart.c_str() + 1); } else { width = screen.stringWidth(lineStart.c_str()); - screen.gPrint(Common::Point(53, yp), PEN_COLOR, lineStart.c_str()); - } + screen.gPrint(Common::Point(53, yp), PEN_COLOR, "%s", lineStart.c_str()); + } // Print out the found keyword Common::String lineMatch(matchP, matchP + _find.size()); - screen.gPrint(Common::Point(53 + width, yp), INV_FOREGROUND, lineMatch.c_str()); + screen.gPrint(Common::Point(53 + width, yp), INV_FOREGROUND, "%s", lineMatch.c_str()); width += screen.stringWidth(lineMatch.c_str()); // Print remainder of line - screen.gPrint(Common::Point(53 + width, yp), PEN_COLOR, matchP + _find.size()); + screen.gPrint(Common::Point(53 + width, yp), PEN_COLOR, "%s", matchP + _find.size()); } else if (_lines[temp].hasPrefix("@")) { - screen.gPrint(Common::Point(53, yp), 15, _lines[temp].c_str() + 1); + screen.gPrint(Common::Point(53, yp), 15, "%s", _lines[temp].c_str() + 1); } else { - screen.gPrint(Common::Point(53, yp), PEN_COLOR, _lines[temp].c_str()); + screen.gPrint(Common::Point(53, yp), PEN_COLOR, "%s", _lines[temp].c_str()); } } else { if (_lines[temp].hasPrefix("@")) { - screen.gPrint(Common::Point(53, yp), 15, _lines[temp].c_str() + 1); + screen.gPrint(Common::Point(53, yp), 15, "%s", _lines[temp].c_str() + 1); } else { - screen.gPrint(Common::Point(53, yp), PEN_COLOR, _lines[temp].c_str()); + screen.gPrint(Common::Point(53, yp), PEN_COLOR, "%s", _lines[temp].c_str()); } } @@ -1033,7 +1033,7 @@ int Journal::getSearchString(bool printError) { INV_FOREGROUND, "Text Not Found !"); } else if (!_find.empty()) { // There's already a search term, display it already - screen.gPrint(Common::Point(15, 185), TALK_FOREGROUND, _find.c_str()); + screen.gPrint(Common::Point(15, 185), TALK_FOREGROUND, "%s", _find.c_str()); name = _find; } @@ -1051,7 +1051,7 @@ int Journal::getSearchString(bool printError) { screen.fillRect(Common::Rect(13, 186, 306, 195), BUTTON_MIDDLE); if (!_find.empty()) { - screen.gPrint(Common::Point(15, 185), TALK_FOREGROUND, _find.c_str()); + screen.gPrint(Common::Point(15, 185), TALK_FOREGROUND, "%s", _find.c_str()); name = _find; } diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index ed2912edc9..96442893ef 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -349,9 +349,9 @@ void Map::showPlaceName(int idx, bool highlighted) { if (highlighted) { int xp = (SHERLOCK_SCREEN_WIDTH - screen.stringWidth(name)) / 2; - screen.gPrint(Common::Point(xp + 2, 2), 0, name.c_str()); - screen.gPrint(Common::Point(xp + 1, 1), 0, name.c_str()); - screen.gPrint(Common::Point(xp, 0), 12, name.c_str()); + screen.gPrint(Common::Point(xp + 2, 2), 0, "%s", name.c_str()); + screen.gPrint(Common::Point(xp + 1, 1), 0, "%s", name.c_str()); + screen.gPrint(Common::Point(xp, 0), 12, "%s", name.c_str()); screen.slamArea(xp, 0, width + 2, 15); } diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 94457b3dd5..02f2526ae9 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -865,13 +865,13 @@ int Object::checkNameForCodes(const Common::String &name, const char *const mess int messageNum = atoi(name.c_str() + 1); ui._infoFlag = true; ui.clearInfo(); - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, messages[messageNum]); + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", messages[messageNum]); ui._menuCounter = 25; } else if (name.hasPrefix("@")) { // Message attached to canimation ui._infoFlag = true; ui.clearInfo(); - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, name.c_str() + 1); + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", name.c_str() + 1); printed = true; ui._menuCounter = 25; } @@ -955,7 +955,7 @@ int Object::pickUpObject(const char *const messages[]) { ui._infoFlag = true; ui.clearInfo(); - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, messages[message]); + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", messages[message]); ui._menuCounter = 30; } else { // Pick it up diff --git a/engines/sherlock/scalpel/darts.cpp b/engines/sherlock/scalpel/darts.cpp index 96d272fed0..de93621e2f 100644 --- a/engines/sherlock/scalpel/darts.cpp +++ b/engines/sherlock/scalpel/darts.cpp @@ -235,10 +235,10 @@ void Darts::showNames(int playerNum) { if (playerNum != 0) screen.print(Common::Point(STATUS_INFO_X + 50, STATUS_INFO_Y), PLAYER_COLOR + 3, - _opponent.c_str()); + "%s", _opponent.c_str()); else screen.print(Common::Point(STATUS_INFO_X + 50, STATUS_INFO_Y), color, - _opponent.c_str()); + "%s", _opponent.c_str()); screen._backBuffer1.fillRect(Common::Rect(STATUS_INFO_X + 50, STATUS_INFO_Y + 10, STATUS_INFO_X + 81, STATUS_INFO_Y + 12), color); diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 1d3c0e0dbf..e70d0614d1 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -369,16 +369,16 @@ void Screen::buttonPrint(const Common::Point &pt, byte color, bool slamIt, if (slamIt) { print(Common::Point(xStart, pt.y + 1), COMMAND_HIGHLIGHTED, "%c", str[0]); print(Common::Point(xStart + charWidth(str[0]), pt.y + 1), - COMMAND_FOREGROUND, str.c_str() + 1); + COMMAND_FOREGROUND, "%s", str.c_str() + 1); } else { gPrint(Common::Point(xStart, pt.y), COMMAND_HIGHLIGHTED, "%c", str[0]); gPrint(Common::Point(xStart + charWidth(str[0]), pt.y), - COMMAND_FOREGROUND, str.c_str() + 1); + COMMAND_FOREGROUND, "%s", str.c_str() + 1); } } else if (slamIt) { - print(Common::Point(xStart, pt.y + 1), color, str.c_str()); + print(Common::Point(xStart, pt.y + 1), color, "%s", str.c_str()); } else { - gPrint(Common::Point(xStart, pt.y), color, str.c_str()); + gPrint(Common::Point(xStart, pt.y), color, "%s", str.c_str()); } } diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index ee9e800cdc..a2c0aa3c84 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -145,12 +145,12 @@ public: * Prints the text passed onto the back buffer at the given position and color. * The string is then blitted to the screen */ - void print(const Common::Point &pt, byte color, const char *formatStr, ...); + void print(const Common::Point &pt, byte color, const char *formatStr, ...) GCC_PRINTF(4, 5); /** * Print a strings onto the back buffer without blitting it to the screen */ - void gPrint(const Common::Point &pt, byte color, const char *formatStr, ...); + void gPrint(const Common::Point &pt, byte color, const char *formatStr, ...) GCC_PRINTF(4, 5); /** * Copies a section of the second back buffer into the main back buffer diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 47b9f6f277..bd4e8c2e78 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -772,23 +772,23 @@ int Talk::talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt // Are we drawing the first line? if (lineStartP == msg.c_str()) { // We are, so print the number and then the text - screen.print(Common::Point(16, lineY), color, number.c_str()); + screen.print(Common::Point(16, lineY), color, "%s", number.c_str()); } // Draw the line with an indent - screen.print(Common::Point(30, lineY), color, sLine.c_str()); + screen.print(Common::Point(30, lineY), color, "%s", sLine.c_str()); } else { - screen.print(Common::Point(16, lineY), color, sLine.c_str()); + screen.print(Common::Point(16, lineY), color, "%s", sLine.c_str()); } } else { if (numberFlag) { if (lineStartP == msg.c_str()) { - screen.gPrint(Common::Point(16, lineY - 1), color, number.c_str()); + screen.gPrint(Common::Point(16, lineY - 1), color, "%s", number.c_str()); } - screen.gPrint(Common::Point(30, lineY - 1), color, sLine.c_str()); + screen.gPrint(Common::Point(30, lineY - 1), color, "%s", sLine.c_str()); } else { - screen.gPrint(Common::Point(16, lineY - 1), color, sLine.c_str()); + screen.gPrint(Common::Point(16, lineY - 1), color, "%s", sLine.c_str()); } } @@ -1367,7 +1367,7 @@ void Talk::doScript(const Common::String &script) { tempString += str[idx + 1]; str += str[0]; - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, tempString.c_str()); + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", tempString.c_str()); ui._menuCounter = 30; break; @@ -1426,9 +1426,9 @@ void Talk::doScript(const Common::String &script) { // If the window is open, display the name directly on-screen. // Otherwise, simply draw it on the back buffer if (ui._windowOpen) { - screen.print(Common::Point(16, yp), TALK_FOREGROUND, NAMES[_speaker & 127]); + screen.print(Common::Point(16, yp), TALK_FOREGROUND, "%s", NAMES[_speaker & 127]); } else { - screen.gPrint(Common::Point(16, yp - 1), TALK_FOREGROUND, NAMES[_speaker & 127]); + screen.gPrint(Common::Point(16, yp - 1), TALK_FOREGROUND, "%s", NAMES[_speaker & 127]); openTalkWindow = true; } @@ -1466,16 +1466,16 @@ void Talk::doScript(const Common::String &script) { // If the speaker indicates a description file, print it in yellow if (_speaker != -1) { if (ui._windowOpen) { - screen.print(Common::Point(16, yp), COMMAND_FOREGROUND, lineStr.c_str()); + screen.print(Common::Point(16, yp), COMMAND_FOREGROUND, "%s", lineStr.c_str()); } else { - screen.gPrint(Common::Point(16, yp - 1), COMMAND_FOREGROUND, lineStr.c_str()); + screen.gPrint(Common::Point(16, yp - 1), COMMAND_FOREGROUND, "%s", lineStr.c_str()); openTalkWindow = true; } } else { if (ui._windowOpen) { - screen.print(Common::Point(16, yp), COMMAND_FOREGROUND, lineStr.c_str()); + screen.print(Common::Point(16, yp), COMMAND_FOREGROUND, "%s", lineStr.c_str()); } else { - screen.gPrint(Common::Point(16, yp - 1), COMMAND_FOREGROUND, lineStr.c_str()); + screen.gPrint(Common::Point(16, yp - 1), COMMAND_FOREGROUND, "%s", lineStr.c_str()); openTalkWindow = true; } } diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index ed6558c6dd..940fcbca03 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -230,7 +230,7 @@ void UserInterface::handleInput() { if (_help != -1 && !scene._bgShapes[_bgFound]._description.empty() && scene._bgShapes[_bgFound]._description[0] != ' ') screen.print(Common::Point(0, INFO_LINE + 1), - INFO_FOREGROUND, scene._bgShapes[_bgFound]._description.c_str()); + INFO_FOREGROUND, "%s", scene._bgShapes[_bgFound]._description.c_str()); _oldBgFound = _bgFound; } @@ -603,14 +603,14 @@ void UserInterface::lookScreen(const Common::Point &pt) { if (_selector != -1) { screen.print(Common::Point(xStart + width, INFO_LINE + 1), - TALK_FOREGROUND, inv[_selector]._name.c_str()); + TALK_FOREGROUND, "%s", inv[_selector]._name.c_str()); screen.print(Common::Point(xStart + width + width1, INFO_LINE + 1), INFO_FOREGROUND, " on "); screen.print(Common::Point(xStart + width + width1 + width2, INFO_LINE + 1), - INFO_FOREGROUND, tempStr.c_str()); + INFO_FOREGROUND, "%s", tempStr.c_str()); } else { screen.print(Common::Point(xStart + width, INFO_LINE + 1), - INFO_FOREGROUND, tempStr.c_str()); + INFO_FOREGROUND, "%s", tempStr.c_str()); } } else if (temp >= 0 && temp < 1000 && _selector != -1 && scene._bgShapes[temp]._aType == PERSON) { @@ -632,14 +632,14 @@ void UserInterface::lookScreen(const Common::Point &pt) { screen.print(Common::Point(xStart, INFO_LINE + 1), INFO_FOREGROUND, "Give "); screen.print(Common::Point(xStart + width, INFO_LINE + 1), - TALK_FOREGROUND, inv[_selector]._name.c_str()); + TALK_FOREGROUND, "%s", inv[_selector]._name.c_str()); screen.print(Common::Point(xStart + width + width1, INFO_LINE + 1), INFO_FOREGROUND, " to "); screen.print(Common::Point(xStart + width + width1 + width2, INFO_LINE + 1), - INFO_FOREGROUND, tempStr.c_str()); + INFO_FOREGROUND, "%s", tempStr.c_str()); } } else { - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, tempStr.c_str()); + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", tempStr.c_str()); } _infoFlag = true; @@ -664,7 +664,7 @@ void UserInterface::lookInv() { if (temp < inv._holdings) { clearInfo(); screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, - inv[temp]._description.c_str()); + "%s", inv[temp]._description.c_str()); _infoFlag = true; _oldLook = temp; } @@ -1896,7 +1896,7 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { // Print out the line Common::String line(lineStartP, msgP); screen.gPrint(Common::Point(16, CONTROLS_Y + 12 + lineNum * 9), - INV_FOREGROUND, line.c_str()); + INV_FOREGROUND, "%s", line.c_str()); if (!endOfStr) // Start next line at start of the nxet word after space @@ -2148,7 +2148,7 @@ void UserInterface::checkUseAction(const UseType *use, const Common::String &inv } else if (messages == nullptr) { screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "You can't do that."); } else { - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, messages[0]); + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", messages[0]); } _infoFlag = true; @@ -2174,7 +2174,7 @@ void UserInterface::checkAction(ActionType &action, const char *const messages[] // Invalid action, to print error message _infoFlag = true; clearInfo(); - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, messages[action._cAnimNum]); + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", messages[action._cAnimNum]); _infoFlag = true; // Set how long to show the message -- cgit v1.2.3 From e115da8f3dd4622cf0f89f55ce00af415eac251e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 20 May 2015 20:32:04 -0400 Subject: SHERLOCK: Standardised keypress fields as char type --- engines/sherlock/settings.cpp | 4 +-- engines/sherlock/user_interface.cpp | 56 +++++++++++++++++-------------------- engines/sherlock/user_interface.h | 4 +-- 3 files changed, 30 insertions(+), 34 deletions(-) diff --git a/engines/sherlock/settings.cpp b/engines/sherlock/settings.cpp index 9f1549a0b8..b26acde615 100644 --- a/engines/sherlock/settings.cpp +++ b/engines/sherlock/settings.cpp @@ -241,7 +241,7 @@ void Settings::show(SherlockEngine *vm) { if (ui._key == Common::KEYCODE_RETURN || ui._key == Common::KEYCODE_SPACE) { events._pressed = false; events._oldButtons = 0; - ui._keycode = Common::KEYCODE_INVALID; + ui._keyPress = '\0'; events._released = true; } } @@ -327,7 +327,7 @@ void Settings::show(SherlockEngine *vm) { if (updateConfig) vm->saveConfig(); - ui._keycode = Common::KEYCODE_INVALID; + ui._keyPress = '\0'; ui._keyboardInput = false; ui._windowBounds.top = CONTROLS_Y1; ui._key = -1; diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 940fcbca03..92fc89305e 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -91,13 +91,13 @@ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { _bgFound = 0; _oldBgFound = -1; - _keycode = Common::KEYCODE_INVALID; + _keyPress = '\0'; _helpStyle = false; _menuCounter = 0; _menuMode = STD_MODE; _help = _oldHelp = 0; _lookHelp = 0; - _key = _oldKey = 0; + _key = _oldKey = '\0'; _temp = _oldTemp = 0; _temp1 = 0; _invLookFlag = 0; @@ -152,13 +152,13 @@ void UserInterface::handleInput() { Common::Point pt = events.mousePos(); _bgFound = scene.findBgShape(Common::Rect(pt.x, pt.y, pt.x + 1, pt.y + 1)); - _keycode = Common::KEYCODE_INVALID; + _keyPress = '\0'; // Check kbd and set the mouse released flag if Enter or space is pressed. // Otherwise, the pressed _key is stored for later use if (events.kbHit()) { Common::KeyState keyState = events.getKey(); - _keycode = keyState.ascii; + _keyPress = keyState.ascii; if (keyState.keycode == Common::KEYCODE_x && keyState.flags & Common::KBD_ALT) { _vm->quitGame(); @@ -315,8 +315,7 @@ void UserInterface::handleInput() { // // Do input processing // - if (events._pressed || events._released || events._rightPressed || - _keycode != Common::KEYCODE_INVALID || _pause) { + if (events._pressed || events._released || events._rightPressed || _keyPress || _pause) { if (((events._released && (_helpStyle || _help == -1)) || (events._rightReleased && !_helpStyle)) && (pt.y <= CONTROLS_Y) && (_menuMode == STD_MODE)) { // The mouse was clicked in the playing area with no action buttons down. @@ -383,9 +382,8 @@ void UserInterface::handleInput() { // As long as there isn't an open window, do main input processing. // Windows are opened when in TALK, USE, INV, and GIVE modes if ((!_windowOpen && !_menuCounter && pt.y > CONTROLS_Y) || - _keycode != Common::KEYCODE_INVALID) { - if (events._pressed || events._released || _pause || - _keycode != Common::KEYCODE_INVALID) + _keyPress) { + if (events._pressed || events._released || _pause || _keyPress) doMainControl(); } @@ -716,8 +714,8 @@ void UserInterface::doEnvControl() { saves._envMode = SAVEMODE_NONE; } - if (_keycode) { - _key = toupper(_keycode); + if (_keyPress) { + _key = toupper(_keyPress); // Escape _key will close the dialog if (_key == Common::KEYCODE_ESCAPE) @@ -769,7 +767,7 @@ void UserInterface::doEnvControl() { _windowBounds.top = CONTROLS_Y1; events._pressed = events._released = _keyboardInput = false; - _keycode = Common::KEYCODE_INVALID; + _keyPress = '\0'; } else if ((found == 1 && events._released) || _key == 'L') { saves._envMode = SAVEMODE_LOAD; if (_selector != -1) { @@ -787,7 +785,7 @@ void UserInterface::doEnvControl() { banishWindow(1); _windowBounds.top = CONTROLS_Y1; _key = _oldKey = -1; - _keycode = Common::KEYCODE_INVALID; + _keyPress = '\0'; _keyboardInput = false; } else { if (!talk._talkToAbort) { @@ -903,11 +901,11 @@ void UserInterface::doEnvControl() { if (_key == Common::KEYCODE_ESCAPE) _key = 'N'; - if (_key == Common::KEYCODE_RETURN || _key == Common::KEYCODE_SPACE) { + if (_key == Common::KEYCODE_RETURN || _key == ' ') { events._pressed = false; events._released = true; events._oldButtons = 0; - _keycode = Common::KEYCODE_INVALID; + _keyPress = '\0'; } } @@ -957,7 +955,7 @@ void UserInterface::doEnvControl() { banishWindow(); _windowBounds.top = CONTROLS_Y1; _key = _oldKey = -1; - _keycode = Common::KEYCODE_INVALID; + _keyPress = '\0'; _keyboardInput = false; } else { if (!talk._talkToAbort) { @@ -1041,12 +1039,12 @@ void UserInterface::doInvControl() { _selector = -1; } - if (_keycode != Common::KEYCODE_INVALID) { - _key = toupper(_keycode); + if (_keyPress) { + _key = toupper(_keyPress); if (_key == Common::KEYCODE_ESCAPE) // Escape will also 'E'xit out of inventory display - _key = Common::KEYCODE_e; + _key = 'E'; if (_key == 'E' || _key == 'L' || _key == 'U' || _key == 'G' || _key == '-' || _key == '+') { @@ -1106,16 +1104,14 @@ void UserInterface::doInvControl() { inv.loadGraphics(); inv.putInv(SLAM_DISPLAY); inv.invCommands(true); - } else if (((found == 5 && events._released) || _key == Common::KEYCODE_MINUS - || _key == Common::KEYCODE_KP_MINUS) && inv._invIndex > 0) { + } else if (((found == 5 && events._released) || _key == '-') && inv._invIndex > 0) { --inv._invIndex; screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1), COMMAND_HIGHLIGHTED, "^"); inv.freeGraphics(); inv.loadGraphics(); inv.putInv(SLAM_DISPLAY); inv.invCommands(true); - } else if (((found == 6 && events._released) || _key == Common::KEYCODE_PLUS - || _key == Common::KEYCODE_KP_PLUS) && (inv._holdings - inv._invIndex) > 6) { + } else if (((found == 6 && events._released) || _key == '+') && (inv._holdings - inv._invIndex) > 6) { ++inv._invIndex; screen.print(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1 + 1), COMMAND_HIGHLIGHTED, "_"); inv.freeGraphics(); @@ -1208,7 +1204,7 @@ void UserInterface::doLookControl() { Screen &screen = *_vm->_screen; _key = _oldKey = -1; - _keyboardInput = (_keycode != Common::KEYCODE_INVALID); + _keyboardInput = (_keyPress != '\0'); if (events._released || events._rightReleased || _keyboardInput) { // Is an inventory object being looked at? @@ -1281,12 +1277,12 @@ void UserInterface::doMainControl() { _key = COMMANDS[_temp]; } --_temp; - } else if (_keycode != Common::KEYCODE_INVALID) { + } else if (_keyPress) { // Keyboard control _keyboardInput = true; - if (_keycode >= Common::KEYCODE_a && _keycode <= Common::KEYCODE_z) { - const char *c = strchr(COMMANDS, _keycode); + if (_keyPress >= 'A' && _keyPress <= 'Z') { + const char *c = strchr(COMMANDS, _keyPress); _temp = !c ? 12 : c - COMMANDS; } else { _temp = 12; @@ -1515,8 +1511,8 @@ void UserInterface::doTalkControl() { _selector = -1; } - if (_keycode != Common::KEYCODE_INVALID) { - _key = toupper(_keycode); + if (_keyPress) { + _key = toupper(_keyPress); if (_key == Common::KEYCODE_ESCAPE) _key = 'E'; @@ -1757,7 +1753,7 @@ void UserInterface::journalControl() { // Finish up _infoFlag = _keyboardInput = false; - _keycode = Common::KEYCODE_INVALID; + _keyPress = '\0'; _windowOpen = false; _windowBounds.top = CONTROLS_Y1; _key = -1; diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index 9fe69cde18..1f7b5feaab 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -73,10 +73,10 @@ private: ImageFile *_controls; int _bgFound; int _oldBgFound; - int _keycode; + char _keyPress; int _lookHelp; int _help, _oldHelp; - int _key, _oldKey; + char _key, _oldKey; int _temp, _oldTemp; int _oldLook; bool _keyboardInput; -- cgit v1.2.3 From a57f569244b9d402e689de5e5f488da935bc4bed Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 20 May 2015 20:56:04 -0400 Subject: SHERLOCK: Fix display of 'Text Not Found' when doing journal searches --- engines/sherlock/journal.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 5a8338bdc8..7ff4272b82 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -1041,6 +1041,7 @@ int Journal::getSearchString(bool printError) { if (printError) { // Give time for user to see the message + events.setButtonState(); for (int idx = 0; idx < 40 && !_vm->shouldQuit() && !events.kbHit() && !events._released; ++idx) { events.pollEvents(); events.setButtonState(); @@ -1048,7 +1049,7 @@ int Journal::getSearchString(bool printError) { } events.clearKeyboard(); - screen.fillRect(Common::Rect(13, 186, 306, 195), BUTTON_MIDDLE); + screen._backBuffer1.fillRect(Common::Rect(13, 186, 306, 195), BUTTON_MIDDLE); if (!_find.empty()) { screen.gPrint(Common::Point(15, 185), TALK_FOREGROUND, "%s", _find.c_str()); -- cgit v1.2.3 From 6a8e3173555c7a34749bcf4b905dec20178bbf5f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 20 May 2015 21:02:58 -0400 Subject: SHERLOCK: Constants fixes in UserInterface --- engines/sherlock/user_interface.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 92fc89305e..4781f4811b 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -682,6 +682,7 @@ void UserInterface::doEnvControl() { Talk &talk = *_vm->_talk; Common::Point mousePos = events.mousePos(); static const char ENV_COMMANDS[7] = "ELSUDQ"; + byte color; _key = _oldKey = -1; @@ -710,7 +711,7 @@ void UserInterface::doEnvControl() { // Handle selecting buttons, if any saves.highlightButtons(found); - if (found == 0 || found == ONSCREEN_FILES_COUNT) + if (found == 0 || found == 5) saves._envMode = SAVEMODE_NONE; } @@ -869,7 +870,7 @@ void UserInterface::doEnvControl() { moreKeys = _key == 'D'; } } while (saves._savegameIndex < (MAX_SAVEGAME_SLOTS - ONSCREEN_FILES_COUNT) && moreKeys); - } else if ((found == ONSCREEN_FILES_COUNT && events._released) || _key == 'Q') { + } else if ((found == 5 && events._released) || _key == 'Q') { clearWindow(); screen.print(Common::Point(0, CONTROLS_Y + 20), INV_FOREGROUND, "Are you sure you wish to Quit ?"); screen.vgaBar(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y + 10), BORDER_COLOR); @@ -1867,7 +1868,7 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { // Loop through displaying up to five lines bool endOfStr = false; const char *msgP = str.c_str(); - for (int lineNum = 0; lineNum < 5 && !endOfStr; ++lineNum) { + for (int lineNum = 0; lineNum < ONSCREEN_FILES_COUNT && !endOfStr; ++lineNum) { int width = 0; const char *lineStartP = msgP; -- cgit v1.2.3 From 46e85f389f4fb9f3d956c42e77345f79701d7a93 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 20 May 2015 21:15:33 -0400 Subject: SHERLOCK: Go to save mode when clicking empty save slot --- engines/sherlock/saveload.cpp | 6 +++++- engines/sherlock/saveload.h | 5 +++++ engines/sherlock/user_interface.cpp | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index c13d6dd9ee..077df7494f 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -401,7 +401,7 @@ bool SaveManager::promptForDescription(int slot) { screen.buttonPrint(Common::Point(ENV_POINTS[5][2], CONTROLS_Y), COMMAND_NULL, true, "Quit"); Common::String saveName = _savegames[slot]; - if (saveName.equalsIgnoreCase(EMPTY_SAVEGAME_SLOT)) { + if (isSlotEmpty(slot)) { // It's an empty slot, so start off with an empty save name saveName = ""; @@ -477,4 +477,8 @@ bool SaveManager::promptForDescription(int slot) { return done == 1; } +bool SaveManager::isSlotEmpty(int slot) const { + return _savegames[slot].equalsIgnoreCase(EMPTY_SAVEGAME_SLOT); +} + } // End of namespace Sherlock diff --git a/engines/sherlock/saveload.h b/engines/sherlock/saveload.h index 066d983b26..a7ed852a5f 100644 --- a/engines/sherlock/saveload.h +++ b/engines/sherlock/saveload.h @@ -135,6 +135,11 @@ public: * Prompts the user to enter a description in a given slot */ bool promptForDescription(int slot); + + /** + * Returns true if the given save slot is empty + */ + bool isSlotEmpty(int slot) const; }; } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 4781f4811b..524ecf3d2f 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -946,7 +946,7 @@ void UserInterface::doEnvControl() { // Are we already in Load mode? if (saves._envMode == SAVEMODE_LOAD) { saves.loadGame(_selector + 1); - } else if (saves._envMode == SAVEMODE_SAVE || _selector == MAX_SAVEGAME_SLOTS) { + } else if (saves._envMode == SAVEMODE_SAVE || saves.isSlotEmpty(_selector)) { // We're already in save mode, or pointing to an empty save slot if (saves.checkGameOnScreen(_selector)) _oldSelector = _selector; -- cgit v1.2.3 From feff241ef7bd4552d44d1e3fa7b3e16f259ca749 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 20 May 2015 21:18:49 -0400 Subject: SHERLOCK: Replace another ONSCREEN_FILES_COUNT value --- engines/sherlock/saveload.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index 077df7494f..ddf4917a34 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -358,7 +358,7 @@ bool SaveManager::checkGameOnScreen(int slot) { Screen &screen = *_vm->_screen; // Check if it's already on-screen - if (slot != -1 && (slot < _savegameIndex || slot >= (_savegameIndex + 5))) { + if (slot != -1 && (slot < _savegameIndex || slot >= (_savegameIndex + ONSCREEN_FILES_COUNT))) { _savegameIndex = slot; screen._backBuffer1.fillRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, -- cgit v1.2.3 From 87fe6a14a069dd5cd02276c2e8e85d25117680d2 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 21 May 2015 19:00:22 -0400 Subject: SHERLOCK: Correct some comments --- engines/sherlock/scalpel/darts.cpp | 2 +- engines/sherlock/talk.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/sherlock/scalpel/darts.cpp b/engines/sherlock/scalpel/darts.cpp index de93621e2f..b567d58ab4 100644 --- a/engines/sherlock/scalpel/darts.cpp +++ b/engines/sherlock/scalpel/darts.cpp @@ -347,7 +347,7 @@ void Darts::drawDartThrow(const Common::Point &pt) { screen._backBuffer1.transBlitFrom(frame, drawPos); screen.slamArea(drawPos.x, drawPos.y, frame._width, frame._height); - // Handle erasing old dart strs + // Handle erasing old dart frame area if (!oldDrawBounds.isEmpty()) screen.slamRect(oldDrawBounds); diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index bd4e8c2e78..5fbf7cc185 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -1435,7 +1435,7 @@ void Talk::doScript(const Common::String &script) { yp += 9; } - // Find amound of text that will fit on the line + // Find amount of text that will fit on the line int width = 0, idx = 0; do { width += screen.charWidth(str[idx]); -- cgit v1.2.3 From 5c30a2c5772049702e1c65d10ae32dec8e6f1cdc Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 21 May 2015 20:07:54 -0400 Subject: SHERLOCK: Clean up initialization and handling of NPC data --- engines/sherlock/journal.cpp | 9 ++- engines/sherlock/people.cpp | 142 +-------------------------------- engines/sherlock/people.h | 12 ++- engines/sherlock/scalpel/scalpel.cpp | 148 ++++++++++++++++++++++++++++++++++- engines/sherlock/talk.cpp | 27 +++---- engines/sherlock/talk.h | 8 +- 6 files changed, 173 insertions(+), 173 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 7ff4272b82..50802f1625 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -131,6 +131,7 @@ void Journal::loadJournalLocations() { } void Journal::loadJournalFile(bool alreadyLoaded) { + People &people = *_vm->_people; Screen &screen = *_vm->_screen; Talk &talk = *_vm->_talk; JournalEntry &journalEntry = _journal[_index]; @@ -152,7 +153,7 @@ void Journal::loadJournalFile(bool alreadyLoaded) { // Find the person being referred to talk._talkTo = -1; for (int idx = 0; idx < MAX_PEOPLE; ++idx) { - Common::String portrait = PORTRAITS[idx]; + Common::String portrait = people[idx]._portrait; Common::String numStr(portrait.c_str(), portrait.c_str() + 4); if (locStr == numStr) { @@ -222,7 +223,7 @@ void Journal::loadJournalFile(bool alreadyLoaded) { journalString += "the Inspector"; break; default: - journalString += NAMES[talk._talkTo]; + journalString += people._characters[talk._talkTo]._name; break; } journalString += ", \""; @@ -283,7 +284,7 @@ void Journal::loadJournalFile(bool alreadyLoaded) { else if (talk._talkTo == 2) journalString += "The Inspector"; else - journalString += NAMES[talk._talkTo]; + journalString += people._characters[talk._talkTo]._name; const byte *strP = replyP + 1; byte v; @@ -330,7 +331,7 @@ void Journal::loadJournalFile(bool alreadyLoaded) { else if (c == 2) journalString += "the Inspector"; else - journalString += NAMES[c]; + journalString += people._characters[c]._name; const byte *strP = replyP; byte v; diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 3a169fa99c..3a630fdd99 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -50,144 +50,6 @@ static const uint8 CHARACTER_SEQUENCES[MAX_HOLMES_SEQUENCE][MAX_FRAME] = { { 52, 1, 2, 3, 4, 0 } // Goto Stand Down Left }; -const char PORTRAITS[MAX_PEOPLE][5] = { - { "HOLM" }, // Sherlock Holmes - { "WATS" }, // Dr. Watson - { "LEST" }, // Inspector Lestrade - { "CON1" }, // Constable O'Brien - { "CON2" }, // Constable Lewis - { "SHEI" }, // Sheila Parker - { "HENR" }, // Henry Carruthers - { "LESL" }, // Lesley (flower girl) - { "USH1" }, // Usher #1 - { "USH2" }, // Usher #2 - { "FRED" }, // Fredrick Epstein - { "WORT" }, // Mrs. Worthington - { "COAC" }, // Coach - { "PLAY" }, // Player - { "WBOY" }, // Tim (Waterboy) - { "JAME" }, // James Sanders - { "BELL" }, // Belle (perfumerie) - { "GIRL" }, // Cleaning Girl (perfumerie) - { "EPST" }, // Epstien in the Opera Balcony - { "WIGG" }, // Wiggins - { "PAUL" }, // Paul (Brumwell / Carroway) - { "BART" }, // Bartender - { "DIRT" }, // Dirty Drunk - { "SHOU" }, // Shouting Drunk - { "STAG" }, // Staggering Drunk - { "BOUN" }, // Bouncer - { "SAND" }, // James Sanders - At Home - { "CORO" }, // The Coroner - { "EQUE" }, // The Equestrian Shop Keeper - { "GEOR" }, // George Blackwood - { "LARS" }, // Lars - { "PARK" }, // Sheila Parker (happy) - { "CHEM" }, // Chemist - { "GREG" }, // Inspector Gregson - { "LAWY" }, // Jacob Farthington Lawyer - { "MYCR" }, // Mycroft - { "SHER" }, // Old Sherman - { "CHMB" }, // Richard Chemist Stock boy - { "BARM" }, // Barman - { "DAND" }, // Dandy Player - { "ROUG" }, // Rough-looking Player - { "SPEC" }, // Spectator - { "HUNT" }, // Robert Hunt - { "VIOL" }, // Violet Secretary - { "PETT" }, // Pettigrew - { "APPL" }, // Augie (apple seller) - { "ANNA" }, // Anna Carroway - { "GUAR" }, // Guard - { "ANTO" }, // Antonio Caruso - { "TOBY" }, // Toby the Dog - { "KING" }, // Simon Kingsley - { "ALFR" }, // Alfred Tobacco Clerk - { "LADY" }, // Lady Brumwell - { "ROSA" }, // Madame Rosa - { "LADB" }, // Lady Brumwell - { "MOOR" }, // Joseph Moorehead - { "BEAL" }, // Mrs. Beale - { "LION" }, // Felix the Lion - { "HOLL" }, // Hollingston - { "CALL" }, // Constable Callaghan - { "JERE" }, // Sergeant Jeremy Duncan - { "LORD" }, // Lord Brumwell - { "NIGE" }, // Nigel Jameson - { "JONA" }, // Jonas (newspaper seller) - { "DUGA" }, // Constable Dugan - { "INSP" } // Inspector Lestrade (Scotland Yard) -}; - -const char *const NAMES[MAX_PEOPLE] = { - "Sherlock Holmes", - "Dr. Watson", - "Inspector Lestrade", - "Constable O'Brien", - "Constable Lewis", - "Sheila Parker", - "Henry Carruthers", - "Lesley", - "An Usher", - "An Usher", - "Fredrick Epstein", - "Mrs. Worthington", - "The Coach", - "A Player", - "Tim", - "James Sanders", - "Belle", - "Cleaning Girl", - "Fredrick Epstein", - "Wiggins", - "Paul", - "The Bartender", - "A Dirty Drunk", - "A Shouting Drunk", - "A Staggering Drunk", - "The Bouncer", - "James Sanders", - "The Coroner", - "Reginald Snipes", - "George Blackwood", - "Lars", - "Sheila Parker", - "The Chemist", - "Inspector Gregson", - "Jacob Farthington", - "Mycroft", - "Old Sherman", - "Richard", - "The Barman", - "A Dandy Player", - "A Rough-looking Player", - "A Spectator", - "Robert Hunt", - "Violet", - "Pettigrew", - "Augie", - "Anna Carroway", - "A Guard", - "Antonio Caruso", - "Toby the Dog", - "Simon Kingsley", - "Alfred", - "Lady Brumwell", - "Madame Rosa", - "Lady Brumwell", - "Joseph Moorehead", - "Mrs. Beale", - "Felix", - "Hollingston", - "Constable Callaghan", - "Sergeant Duncan", - "Lord Brumwell", - "Nigel Jaimeson", - "Jonas", - "Constable Dugan", - "Inspector Lestrade" -}; - /*----------------------------------------------------------------*/ People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) { @@ -591,7 +453,7 @@ int People::findSpeaker(int speaker) { if (obj._type == ACTIVE_BG_SHAPE) { Common::String name(obj._name.c_str(), obj._name.c_str() + 4); - if (name.equalsIgnoreCase(PORTRAITS[speaker]) + if (name.equalsIgnoreCase(_characters[speaker]._portrait) && obj._name[4] >= '0' && obj._name[4] <= '9') return idx; } @@ -639,7 +501,7 @@ void People::setTalking(int speaker) { if (_portraitsOn) { delete _talkPics; - Common::String filename = Common::String::format("%s.vgs", PORTRAITS[speaker]); + Common::String filename = Common::String::format("%s.vgs", _characters[speaker]._portrait); _talkPics = new ImageFile(filename); // Load portrait sequences diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index f22070f5f9..74c057e542 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -53,8 +53,15 @@ enum { MAP_DOWN = 5, MAP_DOWNLEFT = 6, MAP_LEFT = 2, MAP_UPLEFT = 8 }; -extern const char *const NAMES[MAX_PEOPLE]; -extern const char PORTRAITS[MAX_PEOPLE][5]; +struct PersonData { + const char *_name; + const char *_portrait; + const byte *_stillSequences; + const byte *_talkSequences; + + PersonData(const char *name, const char *portrait, const byte *stillSequences, const byte *talkSequences) : + _name(name), _portrait(portrait), _stillSequences(stillSequences), _talkSequences(talkSequences) {} +}; class SherlockEngine; @@ -73,6 +80,7 @@ private: int _oldWalkSequence; int _srcZone, _destZone; public: + Common::Array _characters; ImageFile *_talkPics; Common::Point _walkDest; Common::Point _hSavedPos; diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 56c1e28dbe..d55517cdc3 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -89,7 +89,145 @@ static const byte MAP_SEQUENCES[3][MAX_FRAME] = { #define MAX_PEOPLE 66 -static const byte STILL_SEQUENCES[MAX_PEOPLE][MAX_TALK_SEQUENCES] = { +const char PEOPLE_PORTRAITS[MAX_PEOPLE][5] = { + { "HOLM" }, // Sherlock Holmes + { "WATS" }, // Dr. Watson + { "LEST" }, // Inspector Lestrade + { "CON1" }, // Constable O'Brien + { "CON2" }, // Constable Lewis + { "SHEI" }, // Sheila Parker + { "HENR" }, // Henry Carruthers + { "LESL" }, // Lesley (flower girl) + { "USH1" }, // Usher #1 + { "USH2" }, // Usher #2 + { "FRED" }, // Fredrick Epstein + { "WORT" }, // Mrs. Worthington + { "COAC" }, // Coach + { "PLAY" }, // Player + { "WBOY" }, // Tim (Waterboy) + { "JAME" }, // James Sanders + { "BELL" }, // Belle (perfumerie) + { "GIRL" }, // Cleaning Girl (perfumerie) + { "EPST" }, // Epstien in the Opera Balcony + { "WIGG" }, // Wiggins + { "PAUL" }, // Paul (Brumwell / Carroway) + { "BART" }, // Bartender + { "DIRT" }, // Dirty Drunk + { "SHOU" }, // Shouting Drunk + { "STAG" }, // Staggering Drunk + { "BOUN" }, // Bouncer + { "SAND" }, // James Sanders - At Home + { "CORO" }, // The Coroner + { "EQUE" }, // The Equestrian Shop Keeper + { "GEOR" }, // George Blackwood + { "LARS" }, // Lars + { "PARK" }, // Sheila Parker (happy) + { "CHEM" }, // Chemist + { "GREG" }, // Inspector Gregson + { "LAWY" }, // Jacob Farthington Lawyer + { "MYCR" }, // Mycroft + { "SHER" }, // Old Sherman + { "CHMB" }, // Richard Chemist Stock boy + { "BARM" }, // Barman + { "DAND" }, // Dandy Player + { "ROUG" }, // Rough-looking Player + { "SPEC" }, // Spectator + { "HUNT" }, // Robert Hunt + { "VIOL" }, // Violet Secretary + { "PETT" }, // Pettigrew + { "APPL" }, // Augie (apple seller) + { "ANNA" }, // Anna Carroway + { "GUAR" }, // Guard + { "ANTO" }, // Antonio Caruso + { "TOBY" }, // Toby the Dog + { "KING" }, // Simon Kingsley + { "ALFR" }, // Alfred Tobacco Clerk + { "LADY" }, // Lady Brumwell + { "ROSA" }, // Madame Rosa + { "LADB" }, // Lady Brumwell + { "MOOR" }, // Joseph Moorehead + { "BEAL" }, // Mrs. Beale + { "LION" }, // Felix the Lion + { "HOLL" }, // Hollingston + { "CALL" }, // Constable Callaghan + { "JERE" }, // Sergeant Jeremy Duncan + { "LORD" }, // Lord Brumwell + { "NIGE" }, // Nigel Jameson + { "JONA" }, // Jonas (newspaper seller) + { "DUGA" }, // Constable Dugan + { "INSP" } // Inspector Lestrade (Scotland Yard) +}; + +const char *const PEOPLE_NAMES[MAX_PEOPLE] = { + "Sherlock Holmes", + "Dr. Watson", + "Inspector Lestrade", + "Constable O'Brien", + "Constable Lewis", + "Sheila Parker", + "Henry Carruthers", + "Lesley", + "An Usher", + "An Usher", + "Fredrick Epstein", + "Mrs. Worthington", + "The Coach", + "A Player", + "Tim", + "James Sanders", + "Belle", + "Cleaning Girl", + "Fredrick Epstein", + "Wiggins", + "Paul", + "The Bartender", + "A Dirty Drunk", + "A Shouting Drunk", + "A Staggering Drunk", + "The Bouncer", + "James Sanders", + "The Coroner", + "Reginald Snipes", + "George Blackwood", + "Lars", + "Sheila Parker", + "The Chemist", + "Inspector Gregson", + "Jacob Farthington", + "Mycroft", + "Old Sherman", + "Richard", + "The Barman", + "A Dandy Player", + "A Rough-looking Player", + "A Spectator", + "Robert Hunt", + "Violet", + "Pettigrew", + "Augie", + "Anna Carroway", + "A Guard", + "Antonio Caruso", + "Toby the Dog", + "Simon Kingsley", + "Alfred", + "Lady Brumwell", + "Madame Rosa", + "Lady Brumwell", + "Joseph Moorehead", + "Mrs. Beale", + "Felix", + "Hollingston", + "Constable Callaghan", + "Sergeant Duncan", + "Lord Brumwell", + "Nigel Jaimeson", + "Jonas", + "Constable Dugan", + "Inspector Lestrade" +}; + +static const byte PEOPLE_STILL_SEQUENCES[MAX_PEOPLE][MAX_TALK_SEQUENCES] = { { 1, 0, 0 }, // Sherlock Holmes { 6, 0, 0 }, // Dr. Watson { 4, 0, 0 }, // Inspector Lestrade @@ -158,7 +296,7 @@ static const byte STILL_SEQUENCES[MAX_PEOPLE][MAX_TALK_SEQUENCES] = { { 4, 0, 0 } // Inspector Lestrade (Yard) }; -static const byte TALK_SEQUENCES[MAX_PEOPLE][MAX_TALK_SEQUENCES] = { +static const byte PEOPLE_TALK_SEQUENCES[MAX_PEOPLE][MAX_TALK_SEQUENCES] = { { 1, 0, 0 }, // Sherlock Holmes { 5, 5, 6, 7, 8, 7, 8, 6, 0, 0 }, // Dr. Watson { 2, 0, 0 }, // Inspector Lestrade @@ -258,8 +396,10 @@ void ScalpelEngine::initialize() { // Load the inventory loadInventory(); - // Set up constants used by the talk system - _talk->setSequences(&TALK_SEQUENCES[0][0], &STILL_SEQUENCES[0][0], MAX_PEOPLE); + // Set up list of people + for (int idx = 0; idx < MAX_PEOPLE; ++idx) + _people->_characters.push_back(PersonData(PEOPLE_NAMES[idx], PEOPLE_PORTRAITS[idx], + PEOPLE_STILL_SEQUENCES[idx], PEOPLE_TALK_SEQUENCES[idx])); _animation->setPrologueNames(&PROLOGUE_NAMES[0], PROLOGUE_NAMES_COUNT); _animation->setPrologueFrames(&PROLOGUE_FRAMES[0][0], 6, 9); diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 5fbf7cc185..6bac16c9bf 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -105,15 +105,6 @@ Talk::Talk(SherlockEngine *vm) : _vm(vm) { _scriptSaveIndex = -1; } -void Talk::setSequences(const byte *talkSequences, const byte *stillSequences, int maxPeople) { - for (int idx = 0; idx < maxPeople; ++idx) { - STILL_SEQUENCES.push_back(TalkSequences(stillSequences)); - TALK_SEQUENCES.push_back(TalkSequences(talkSequences)); - stillSequences += MAX_TALK_SEQUENCES; - talkSequences += MAX_TALK_SEQUENCES; - } -} - void Talk::talkTo(const Common::String &filename) { Events &events = *_vm->_events; Inventory &inv = *_vm->_inventory; @@ -537,6 +528,7 @@ void Talk::freeTalkVars() { } void Talk::loadTalkFile(const Common::String &filename) { + People &people = *_vm->_people; Resources &res = *_vm->_res; Sound &sound = *_vm->_sound; @@ -546,7 +538,7 @@ void Talk::loadTalkFile(const Common::String &filename) { // Check for an existing person being talked to _talkTo = -1; for (int idx = 0; idx < MAX_PEOPLE; ++idx) { - if (!scumm_strnicmp(filename.c_str(), PORTRAITS[idx], 4)) { + if (!scumm_strnicmp(filename.c_str(), people._characters[idx]._portrait, 4)) { _talkTo = idx; break; } @@ -884,8 +876,8 @@ void Talk::setSequence(int speaker) { warning("Tried to copy too many talk frames"); } else { for (int idx = 0; idx < MAX_TALK_SEQUENCES; ++idx) { - obj._sequences[idx] = TALK_SEQUENCES[speaker][idx]; - if (idx > 0 && !TALK_SEQUENCES[speaker][idx] && !TALK_SEQUENCES[speaker][idx - 1]) + obj._sequences[idx] = people._characters[speaker]._talkSequences[idx]; + if (idx > 0 && !obj._sequences[idx] && !obj._sequences[idx - 1]) return; obj._frameNumber = 0; @@ -913,8 +905,9 @@ void Talk::setStillSeq(int speaker) { warning("Tried to copy too few still frames"); } else { for (uint idx = 0; idx < MAX_TALK_SEQUENCES; ++idx) { - obj._sequences[idx] = STILL_SEQUENCES[speaker][idx]; - if (idx > 0 && !TALK_SEQUENCES[speaker][idx] && !TALK_SEQUENCES[speaker][idx - 1]) + obj._sequences[idx] = people._characters[speaker]._stillSequences[idx]; + if (idx > 0 && !people._characters[speaker]._talkSequences[idx] && + !people._characters[speaker]._talkSequences[idx - 1]) break; } @@ -1426,9 +1419,11 @@ void Talk::doScript(const Common::String &script) { // If the window is open, display the name directly on-screen. // Otherwise, simply draw it on the back buffer if (ui._windowOpen) { - screen.print(Common::Point(16, yp), TALK_FOREGROUND, "%s", NAMES[_speaker & 127]); + screen.print(Common::Point(16, yp), TALK_FOREGROUND, "%s", + people._characters[_speaker & 127]._name); } else { - screen.gPrint(Common::Point(16, yp - 1), TALK_FOREGROUND, "%s", NAMES[_speaker & 127]); + screen.gPrint(Common::Point(16, yp - 1), TALK_FOREGROUND, "%s", + people._characters[_speaker & 127]._name); openTalkWindow = true; } diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index 71f093f66a..d26259dbfd 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -127,9 +127,6 @@ class UserInterface; class Talk { friend class UserInterface; -private: - Common::Array STILL_SEQUENCES; - Common::Array TALK_SEQUENCES; private: SherlockEngine *_vm; Common::Stack _savedSequences; @@ -188,11 +185,8 @@ public: Talk(SherlockEngine *vm); /** - * Sets talk sequences + * Return a given talk statement */ - void setSequences(const byte *talkSequences, const byte *stillSequences, - int maxPeople); - Statement &operator[](int idx) { return _statements[idx]; } /** -- cgit v1.2.3 From bfbeed4f5eb8986f93a3248251b3740e3b9ed6ad Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 21 May 2015 21:23:09 -0400 Subject: SHERLOCK: Replaced second MAX_PEOPLE definition with _characters.size() --- engines/sherlock/journal.cpp | 2 +- engines/sherlock/people.h | 1 - engines/sherlock/talk.cpp | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 50802f1625..564db59042 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -152,7 +152,7 @@ void Journal::loadJournalFile(bool alreadyLoaded) { // Find the person being referred to talk._talkTo = -1; - for (int idx = 0; idx < MAX_PEOPLE; ++idx) { + for (int idx = 0; idx < (int)people._characters.size(); ++idx) { Common::String portrait = people[idx]._portrait; Common::String numStr(portrait.c_str(), portrait.c_str() + 4); diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index 74c057e542..c32681fdd1 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -36,7 +36,6 @@ enum PeopleId { AL = 0, PEG = 1, NUM_OF_PEOPLE = 2, // Holmes and Watson - MAX_PEOPLE = 66 // Total of all NPCs }; // Animation sequence identifiers for characters diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 6bac16c9bf..319d1a383f 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -537,7 +537,7 @@ void Talk::loadTalkFile(const Common::String &filename) { // Check for an existing person being talked to _talkTo = -1; - for (int idx = 0; idx < MAX_PEOPLE; ++idx) { + for (int idx = 0; idx < (int)people._characters.size(); ++idx) { if (!scumm_strnicmp(filename.c_str(), people._characters[idx]._portrait, 4)) { _talkTo = idx; break; @@ -1415,7 +1415,7 @@ void Talk::doScript(const Common::String &script) { } // If it's the first line, display the speaker - if (!line && _speaker >= 0 && _speaker < MAX_PEOPLE) { + if (!line && _speaker >= 0 && _speaker < (int)people._characters.size()) { // If the window is open, display the name directly on-screen. // Otherwise, simply draw it on the back buffer if (ui._windowOpen) { -- cgit v1.2.3 From 50f985217cabb4f5d8912db7071f0822f1899e38 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 21 May 2015 21:26:53 -0400 Subject: SHERLOCK: Rename NUM_OF_PEOPLE for better clarity --- engines/sherlock/people.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index c32681fdd1..8244fd9b59 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -30,12 +30,13 @@ namespace Sherlock { -// People definitions +// Player definitions. The game has theoretical support for two player characters but only the first one is used. +// Watson is, instead, handled by a different sprite in each scene, with a very simple initial movement, if any enum PeopleId { PLAYER = 0, AL = 0, PEG = 1, - NUM_OF_PEOPLE = 2, // Holmes and Watson + MAX_PLAYERS = 2 }; // Animation sequence identifiers for characters @@ -74,7 +75,7 @@ public: class People { private: SherlockEngine *_vm; - Person _data[NUM_OF_PEOPLE]; + Person _data[MAX_PLAYERS]; bool _walkLoaded; int _oldWalkSequence; int _srcZone, _destZone; @@ -101,11 +102,11 @@ public: ~People(); Person &operator[](PeopleId id) { - assert(id < NUM_OF_PEOPLE); + assert(id < MAX_PLAYERS); return _data[id]; } Person &operator[](int idx) { - assert(idx < NUM_OF_PEOPLE); + assert(idx < MAX_PLAYERS); return _data[idx]; } -- cgit v1.2.3