diff options
author | Paul Gilbert | 2018-12-07 20:35:30 -0800 |
---|---|---|
committer | Paul Gilbert | 2018-12-08 19:05:59 -0800 |
commit | f6abb3ea33c7b073066732f794a9d071c38a044d (patch) | |
tree | 1ce41b767ac812a7148c1726723dc849f180b399 /engines/glk/frotz | |
parent | 2ae0edd58ba0258b4f3278e334468b12a0b73573 (diff) | |
download | scummvm-rg350-f6abb3ea33c7b073066732f794a9d071c38a044d.tar.gz scummvm-rg350-f6abb3ea33c7b073066732f794a9d071c38a044d.tar.bz2 scummvm-rg350-f6abb3ea33c7b073066732f794a9d071c38a044d.zip |
GLK: FROTZ: Simplify accessing sounds for Lurking Horror & Sherlock
Diffstat (limited to 'engines/glk/frotz')
-rw-r--r-- | engines/glk/frotz/glk_interface.cpp | 74 | ||||
-rw-r--r-- | engines/glk/frotz/glk_interface.h | 5 | ||||
-rw-r--r-- | engines/glk/frotz/sound_folder.cpp | 146 | ||||
-rw-r--r-- | engines/glk/frotz/sound_folder.h | 138 |
4 files changed, 332 insertions, 31 deletions
diff --git a/engines/glk/frotz/glk_interface.cpp b/engines/glk/frotz/glk_interface.cpp index f800f73a88..79907cbc84 100644 --- a/engines/glk/frotz/glk_interface.cpp +++ b/engines/glk/frotz/glk_interface.cpp @@ -22,8 +22,11 @@ #include "glk/frotz/glk_interface.h" #include "glk/frotz/pics.h" +#include "glk/frotz/sound_folder.h" #include "glk/conf.h" #include "glk/screen.h" +#include "common/config-manager.h" +#include "common/unzip.h" namespace Glk { namespace Frotz { @@ -52,49 +55,49 @@ void GlkInterface::initialize() { * Init glk stuff */ - // monor - glk_stylehint_set(wintype_AllTypes, style_Preformatted, stylehint_Proportional, 0); - glk_stylehint_set(wintype_AllTypes, style_Preformatted, stylehint_Weight, 0); - glk_stylehint_set(wintype_AllTypes, style_Preformatted, stylehint_Oblique, 0); + // monor + glk_stylehint_set(wintype_AllTypes, style_Preformatted, stylehint_Proportional, 0); + glk_stylehint_set(wintype_AllTypes, style_Preformatted, stylehint_Weight, 0); + glk_stylehint_set(wintype_AllTypes, style_Preformatted, stylehint_Oblique, 0); // monob - glk_stylehint_set(wintype_AllTypes, style_Subheader, stylehint_Proportional, 0); - glk_stylehint_set(wintype_AllTypes, style_Subheader, stylehint_Weight, 1); - glk_stylehint_set(wintype_AllTypes, style_Subheader, stylehint_Oblique, 0); + glk_stylehint_set(wintype_AllTypes, style_Subheader, stylehint_Proportional, 0); + glk_stylehint_set(wintype_AllTypes, style_Subheader, stylehint_Weight, 1); + glk_stylehint_set(wintype_AllTypes, style_Subheader, stylehint_Oblique, 0); // monoi - glk_stylehint_set(wintype_AllTypes, style_Alert, stylehint_Proportional, 0); - glk_stylehint_set(wintype_AllTypes, style_Alert, stylehint_Weight, 0); - glk_stylehint_set(wintype_AllTypes, style_Alert, stylehint_Oblique, 1); + glk_stylehint_set(wintype_AllTypes, style_Alert, stylehint_Proportional, 0); + glk_stylehint_set(wintype_AllTypes, style_Alert, stylehint_Weight, 0); + glk_stylehint_set(wintype_AllTypes, style_Alert, stylehint_Oblique, 1); // monoz - glk_stylehint_set(wintype_AllTypes, style_BlockQuote, stylehint_Proportional, 0); - glk_stylehint_set(wintype_AllTypes, style_BlockQuote, stylehint_Weight, 1); - glk_stylehint_set(wintype_AllTypes, style_BlockQuote, stylehint_Oblique, 1); + glk_stylehint_set(wintype_AllTypes, style_BlockQuote, stylehint_Proportional, 0); + glk_stylehint_set(wintype_AllTypes, style_BlockQuote, stylehint_Weight, 1); + glk_stylehint_set(wintype_AllTypes, style_BlockQuote, stylehint_Oblique, 1); // propr - glk_stylehint_set(wintype_TextBuffer, style_Normal, stylehint_Proportional, 1); - glk_stylehint_set(wintype_TextGrid, style_Normal, stylehint_Proportional, 0); - glk_stylehint_set(wintype_AllTypes, style_Normal, stylehint_Weight, 0); - glk_stylehint_set(wintype_AllTypes, style_Normal, stylehint_Oblique, 0); + glk_stylehint_set(wintype_TextBuffer, style_Normal, stylehint_Proportional, 1); + glk_stylehint_set(wintype_TextGrid, style_Normal, stylehint_Proportional, 0); + glk_stylehint_set(wintype_AllTypes, style_Normal, stylehint_Weight, 0); + glk_stylehint_set(wintype_AllTypes, style_Normal, stylehint_Oblique, 0); // propb - glk_stylehint_set(wintype_TextBuffer, style_Header, stylehint_Proportional, 1); - glk_stylehint_set(wintype_TextGrid, style_Header, stylehint_Proportional, 0); - glk_stylehint_set(wintype_AllTypes, style_Header, stylehint_Weight, 1); - glk_stylehint_set(wintype_AllTypes, style_Header, stylehint_Oblique, 0); + glk_stylehint_set(wintype_TextBuffer, style_Header, stylehint_Proportional, 1); + glk_stylehint_set(wintype_TextGrid, style_Header, stylehint_Proportional, 0); + glk_stylehint_set(wintype_AllTypes, style_Header, stylehint_Weight, 1); + glk_stylehint_set(wintype_AllTypes, style_Header, stylehint_Oblique, 0); // propi - glk_stylehint_set(wintype_TextBuffer, style_Emphasized, stylehint_Proportional, 1); - glk_stylehint_set(wintype_TextGrid, style_Emphasized, stylehint_Proportional, 0); - glk_stylehint_set(wintype_AllTypes, style_Emphasized, stylehint_Weight, 0); - glk_stylehint_set(wintype_AllTypes, style_Emphasized, stylehint_Oblique, 1); + glk_stylehint_set(wintype_TextBuffer, style_Emphasized, stylehint_Proportional, 1); + glk_stylehint_set(wintype_TextGrid, style_Emphasized, stylehint_Proportional, 0); + glk_stylehint_set(wintype_AllTypes, style_Emphasized, stylehint_Weight, 0); + glk_stylehint_set(wintype_AllTypes, style_Emphasized, stylehint_Oblique, 1); // propi - glk_stylehint_set(wintype_TextBuffer, style_Note, stylehint_Proportional, 1); - glk_stylehint_set(wintype_TextGrid, style_Note, stylehint_Proportional, 0); - glk_stylehint_set(wintype_AllTypes, style_Note, stylehint_Weight, 1); - glk_stylehint_set(wintype_AllTypes, style_Note, stylehint_Oblique, 1); + glk_stylehint_set(wintype_TextBuffer, style_Note, stylehint_Proportional, 1); + glk_stylehint_set(wintype_TextGrid, style_Note, stylehint_Proportional, 0); + glk_stylehint_set(wintype_AllTypes, style_Note, stylehint_Weight, 1); + glk_stylehint_set(wintype_AllTypes, style_Note, stylehint_Oblique, 1); /* * Get the screen size @@ -123,7 +126,7 @@ void GlkInterface::initialize() { if (h_version >= V4) h_config |= CONFIG_BOLDFACE | CONFIG_EMPHASIS | - CONFIG_FIXED | CONFIG_TIMEDINPUT | CONFIG_COLOUR; + CONFIG_FIXED | CONFIG_TIMEDINPUT | CONFIG_COLOUR; if (h_version >= V5) h_flags &= ~(GRAPHICS_FLAG | MOUSE_FLAG | MENU_FLAG); @@ -134,7 +137,7 @@ void GlkInterface::initialize() { if ((h_version == 3) && (h_flags & OLD_SOUND_FLAG)) h_flags |= OLD_SOUND_FLAG; - if ((h_version == 6) && (_sound != 0)) + if ((h_version == 6) && (_sound != 0)) h_config |= CONFIG_SOUND; if (h_version >= V5 && (h_flags & UNDO_FLAG)) @@ -188,6 +191,15 @@ void GlkInterface::initialize() { // Set the screen colors garglk_set_zcolors(_defaultForeground, _defaultBackground); + + // Add any sound folder or zip + addSound(); +} + +void GlkInterface::addSound() { + Common::FSNode gameDir(ConfMan.get("path")); + SoundSubfolder::check(gameDir); + SoundZip::check(gameDir, _storyId); } bool GlkInterface::initPictures() { diff --git a/engines/glk/frotz/glk_interface.h b/engines/glk/frotz/glk_interface.h index 4e531ee40b..ce5da8a2fb 100644 --- a/engines/glk/frotz/glk_interface.h +++ b/engines/glk/frotz/glk_interface.h @@ -105,6 +105,11 @@ private: * Displays the title screen for the game Beyond Zork */ void showBeyondZorkTitle(); + + /** + * Add any Sound subfolder or sound zip file for access + */ + void addSound(); protected: /** * Return the length of the character in screen units. diff --git a/engines/glk/frotz/sound_folder.cpp b/engines/glk/frotz/sound_folder.cpp new file mode 100644 index 0000000000..20f22a83b4 --- /dev/null +++ b/engines/glk/frotz/sound_folder.cpp @@ -0,0 +1,146 @@ +/* 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 "glk/frotz/sound_folder.h" +#include "common/file.h" +#include "common/unzip.h" + +namespace Glk { +namespace Frotz { + +void SoundSubfolder::check(const Common::FSNode &gameDir) { + Common::FSNode sound = gameDir.getChild("sound"); + if (sound.isDirectory()) + SearchMan.add("sound", new SoundSubfolder(sound)); +} + +SoundSubfolder::SoundSubfolder(const Common::FSNode &folder) : _folder(folder) { + Common::FSList files; + if (folder.getChildren(files, Common::FSNode::kListFilesOnly)) { + for (uint idx = 0; idx < files.size(); ++idx) { + Common::String filename = files[idx].getName(); + if (filename.hasSuffixIgnoreCase(".snd")) { + int fileNum = atoi(filename.c_str() + filename.size() - 6); + Common::String newName = Common::String::format("sound%d.snd", fileNum); + + _filenames[newName] = filename; + } + } + } +} + +bool SoundSubfolder::hasFile(const Common::String &name) const { + return _filenames.contains(name); +} + +int SoundSubfolder::listMembers(Common::ArchiveMemberList &list) const { + int total = 0; + for (Common::StringMap::iterator i = _filenames.begin(); i != _filenames.end(); ++i) { + list.push_back(Common::ArchiveMemberList::value_type(new Common::GenericArchiveMember((*i)._key, this))); + ++total; + } + + return total; +} + +const Common::ArchiveMemberPtr SoundSubfolder::getMember(const Common::String &name) const { + if (!hasFile(name)) + return Common::ArchiveMemberPtr(); + + return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this)); +} + +Common::SeekableReadStream *SoundSubfolder::createReadStreamForMember(const Common::String &name) const { + Common::File *f = new Common::File(); + if (f->open(_folder.getChild(name))) + return f; + + delete f; + return nullptr; +} + +/*--------------------------------------------------------------------------*/ + +void SoundZip::check(const Common::FSNode &gameDir, Story story) { + if (story != LURKING_HORROR && story != SHERLOCK) + return; + Common::String zipName = (story == LURKING_HORROR) ? "lhsound.zip" : "shsound.zip"; + + // Check for the existance of the zip + Common::FSNode zipNode = gameDir.getChild(zipName); + if (!zipNode.exists()) + return; + + SearchMan.add("sound", Common::makeZipArchive(zipNode)); +} + +SoundZip::SoundZip(Common::Archive *zip) : _zip(zip) { + Common::ArchiveMemberList files; + zip->listMembers(files); + + for (Common::ArchiveMemberList::iterator i = files.begin(); i != files.end(); ++i) { + Common::String filename = (*i)->getName(); + if (filename.hasSuffixIgnoreCase(".snd")) { + int fileNum = atoi(filename.c_str() + filename.size() - 6); + Common::String newName = Common::String::format("sound%d.snd", fileNum); + + _filenames[newName] = filename; + } + } +} + +SoundZip::~SoundZip() { + delete _zip; +} + +bool SoundZip::hasFile(const Common::String &name) const { + return _filenames.contains(name); +} + +int SoundZip::listMembers(Common::ArchiveMemberList &list) const { + int total = 0; + + for (Common::StringMap::iterator i = _filenames.begin(); i != _filenames.end(); ++i) { + list.push_back(Common::ArchiveMemberList::value_type(new Common::GenericArchiveMember((*i)._key, this))); + ++total; + } + + return total; +} + +const Common::ArchiveMemberPtr SoundZip::getMember(const Common::String &name) const { + if (!hasFile(name)) + return Common::ArchiveMemberPtr(); + + return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this)); + +} + +Common::SeekableReadStream *SoundZip::createReadStreamForMember(const Common::String &name) const { + if (!_filenames.contains(name)) + return nullptr; + + return _zip->createReadStreamForMember(_filenames[name]); +} + +} // End of namespace Scott +} // End of namespace Glk diff --git a/engines/glk/frotz/sound_folder.h b/engines/glk/frotz/sound_folder.h new file mode 100644 index 0000000000..50eef065b1 --- /dev/null +++ b/engines/glk/frotz/sound_folder.h @@ -0,0 +1,138 @@ +/* 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 GLK_FROTZ_SOUND_FOLDER_H +#define GLK_FROTZ_SOUND_FOLDER_H + +#include "glk/frotz/frotz_types.h" +#include "common/archive.h" +#include "common/fs.h" +#include "common/hash-str.h" + +namespace Glk { +namespace Frotz { + +/** + * Acts as an interface to an Infocom sound subfolder for the Lurking Horror or + * Sherlock. Any file which ends with a number and '.snd' will be accessible as + * 'sound<num>.snd' in the outer Glk layer + */ +class SoundSubfolder : public Common::Archive { +private: + Common::FSNode _folder; + Common::StringMap _filenames; +private: + /** + * Constructor + */ + SoundSubfolder(const Common::FSNode &folder); +public: + /** + * Checks for a sound subfolder, and if so, instantiates the class for it + */ + static void check(const Common::FSNode &gameDir); + + /** + * Check if a member with the given name is present in the Archive. + * Patterns are not allowed, as this is meant to be a quick File::exists() + * replacement. + */ + virtual bool hasFile(const Common::String &name) const override; + + /** + * Add all members of the Archive to list. + * Must only append to list, and not remove elements from it. + * + * @return the number of names added to list + */ + virtual int listMembers(Common::ArchiveMemberList &list) const override; + + /** + * Returns a ArchiveMember representation of the given file. + */ + virtual const Common::ArchiveMemberPtr getMember(const Common::String &name) const override; + + /** + * Create a stream bound to a member with the specified name in the + * archive. If no member with this name exists, 0 is returned. + * @return the newly created input stream + */ + virtual Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override; +}; + +/** + * Acts as an interface to a Zip file from if-archive for the Lurking Horror or + * Sherlock. Any file which ends with a number and '.snd' will be accessible as + * 'sound<num>.snd' in the outer Glk layer + */ +class SoundZip : public Common::Archive { +private: + Common::Archive *_zip; + Common::StringMap _filenames; +private: + /** + * Constructor + */ + SoundZip(Common::Archive *zip); +public: + /** + * Checks for a sound subfolder, and if so, instantiates the class for it + */ + static void check(const Common::FSNode &gameDir, Story story); + + /** + * Destructor + */ + ~SoundZip(); + + /** + * Check if a member with the given name is present in the Archive. + * Patterns are not allowed, as this is meant to be a quick File::exists() + * replacement. + */ + virtual bool hasFile(const Common::String &name) const override; + + /** + * Add all members of the Archive to list. + * Must only append to list, and not remove elements from it. + * + * @return the number of names added to list + */ + virtual int listMembers(Common::ArchiveMemberList &list) const override; + + /** + * Returns a ArchiveMember representation of the given file. + */ + virtual const Common::ArchiveMemberPtr getMember(const Common::String &name) const override; + + /** + * Create a stream bound to a member with the specified name in the + * archive. If no member with this name exists, 0 is returned. + * @return the newly created input stream + */ + virtual Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override; +}; + +} // End of namespace Frotz +} // End of namespace Glk + +#endif |