aboutsummaryrefslogtreecommitdiff
path: root/engines/glk/frotz
diff options
context:
space:
mode:
authorPaul Gilbert2018-12-07 20:35:30 -0800
committerPaul Gilbert2018-12-08 19:05:59 -0800
commitf6abb3ea33c7b073066732f794a9d071c38a044d (patch)
tree1ce41b767ac812a7148c1726723dc849f180b399 /engines/glk/frotz
parent2ae0edd58ba0258b4f3278e334468b12a0b73573 (diff)
downloadscummvm-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.cpp74
-rw-r--r--engines/glk/frotz/glk_interface.h5
-rw-r--r--engines/glk/frotz/sound_folder.cpp146
-rw-r--r--engines/glk/frotz/sound_folder.h138
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