NANCY: Implement sound options, add options dialog

Hooked the engine into ScummVM's speech/subtitle settings, and added two extra options for player and character speech. Added a custom settings dialog which gets shown both inside the Edit Game window and the in-game Settings.
This commit is contained in:
fracturehill 2021-04-04 16:51:01 +03:00
parent 9bb543a69e
commit 9f35d133ca
8 changed files with 172 additions and 14 deletions

View File

@ -1,2 +1,3 @@
engines/nancy/cheat.cpp
engines/nancy/input.cpp
engines/nancy/dialogs.cpp

View File

@ -21,6 +21,7 @@
*/
#include "common/random.h"
#include "common/config-manager.h"
#include "engines/nancy/nancy.h"
#include "engines/nancy/sound.h"
@ -226,7 +227,11 @@ void PlayPrimaryVideoChan0::execute() {
init();
registerGraphics();
g_nancy->_sound->loadSound(_sound);
g_nancy->_sound->playSound(_sound);
if (!ConfMan.getBool("speech_mute") && ConfMan.getBool("character_speech")) {
g_nancy->_sound->playSound(_sound);
}
_state = kRun;
_activePrimaryVideo = this;
// fall through
@ -234,7 +239,10 @@ void PlayPrimaryVideoChan0::execute() {
if (!_hasDrawnTextbox) {
_hasDrawnTextbox = true;
NancySceneState.getTextbox().clear();
NancySceneState.getTextbox().addTextLine(_text);
if (ConfMan.getBool("subtitles")) {
NancySceneState.getTextbox().addTextLine(_text);
}
// Add responses when conditions have been satisfied
if (_conditionalResponseCharacterID != 10) {
@ -270,11 +278,14 @@ void PlayPrimaryVideoChan0::execute() {
}
if (_pickedResponse != -1) {
// Player has picked response, play sound file and change _state
// Player has picked response, play sound file and change state
_responseGenericSound.name = _responses[_pickedResponse].soundName;
// TODO this is probably not correct
g_nancy->_sound->loadSound(_responseGenericSound);
g_nancy->_sound->playSound(_responseGenericSound);
if (!ConfMan.getBool("speech_mute") && ConfMan.getBool("player_speech")) {
g_nancy->_sound->playSound(_responseGenericSound);
}
_state = kActionTrigger;
}
}

View File

@ -21,6 +21,7 @@
*/
#include "engines/nancy/detection.h"
#include "engines/nancy/dialogs.h"
const char *const directoryGlobs[] = {
"game",
@ -193,18 +194,31 @@ public:
_directoryGlobs = directoryGlobs;
}
const char *getEngineId() const override {
virtual const char *getEngineId() const override {
return "nancy";
}
const char *getName() const override {
virtual const char *getName() const override {
return "Nancy Drew";
}
const char *getOriginalCopyright() const override {
virtual const char *getOriginalCopyright() const override {
return "Nancy Drew Engine copyright Her Interactive, 1995-2012";
}
virtual void registerDefaultSettings(const Common::String &target) const override;
virtual GUI::OptionsContainerWidget *buildEngineOptionsWidgetStatic(GUI::GuiObject *boss, const Common::String &name, const Common::String &target) const override;
};
void NancyMetaEngineDetection::registerDefaultSettings(const Common::String &target) const {
ConfMan.setInt("music_volume", 54 * 255 / 100, target);
ConfMan.setInt("speech_volume", 54 * 255 / 100, target);
ConfMan.setInt("sfx_volume", 51 * 255 / 100, target);
ConfMan.setBool("subtitles", true, target);
}
GUI::OptionsContainerWidget *NancyMetaEngineDetection::buildEngineOptionsWidgetStatic(GUI::GuiObject *boss, const Common::String &name, const Common::String &target) const {
return new Nancy::NancyOptionsWidget(boss, name, target);
}
REGISTER_PLUGIN_STATIC(NANCY_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, NancyMetaEngineDetection);

67
engines/nancy/dialogs.cpp Normal file
View File

@ -0,0 +1,67 @@
/* 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/translation.h"
#include "gui/ThemeEval.h"
#include "engines/nancy/dialogs.h"
namespace Nancy {
NancyOptionsWidget::NancyOptionsWidget(GuiObject *boss, const Common::String &name, const Common::String &domain) :
OptionsContainerWidget(boss, name, "NancyOptionsDialog", false, domain) {
_playerSpeechCheckbox = new GUI::CheckboxWidget(widgetsBoss(), "NancyOptionsDialog.PlayerSpeech", _("Player Speech"), _("Enable player speech. Only works if speech is enabled in the Audio settings."));
_characterSpeechCheckbox = new GUI::CheckboxWidget(widgetsBoss(), "NancyOptionsDialog.CharacterSpeech", _("Character Speech"), _("Enable NPC speech. Only works if speech is enabled in the Audio settings."));
new GUI::StaticTextWidget(widgetsBoss(), "NancyOptionsDialog.SpeechSettingsLabel", _("Speech Options"));
}
void NancyOptionsWidget::load() {
_playerSpeechCheckbox->setState(ConfMan.getBool("player_speech", _domain));
_characterSpeechCheckbox->setState(ConfMan.getBool("character_speech", _domain));
}
bool NancyOptionsWidget::save() {
ConfMan.setBool("player_speech", _playerSpeechCheckbox->getState(), _domain);
ConfMan.setBool("character_speech", _characterSpeechCheckbox->getState(), _domain);
return true;
}
void NancyOptionsWidget::defineLayout(GUI::ThemeEval &layouts, const Common::String &layoutName, const Common::String &overlayedLayout) const {
layouts.addDialog(layoutName, overlayedLayout)
.addLayout(GUI::ThemeLayout::kLayoutVertical)
.addPadding(16, 16, 16, 16)
.addWidget("SpeechSettingsLabel", "OptionsLabel")
.addWidget("PlayerSpeech", "Checkbox")
.addWidget("CharacterSpeech", "Checkbox")
.closeLayout()
.closeDialog();
}
bool NancyOptionsWidget::isInGame() const {
return _domain.equals(ConfMan.getActiveDomainName());
}
} // End of namespace Nancy

49
engines/nancy/dialogs.h Normal file
View File

@ -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.
*
*/
#include "engines/dialogs.h"
#ifndef NANCY_DIALOGS_H
#define NANCY_DIALOGS_H
namespace Nancy {
class NancyOptionsWidget : public GUI::OptionsContainerWidget {
public:
NancyOptionsWidget(GuiObject *boss, const Common::String &name, const Common::String &domain);
virtual ~NancyOptionsWidget() override {};
void load() override;
bool save() override;
private:
void defineLayout(GUI::ThemeEval &layouts, const Common::String &layoutName, const Common::String &overlayedLayout) const override;
bool isInGame() const;
GUI::CheckboxWidget *_playerSpeechCheckbox;
GUI::CheckboxWidget *_characterSpeechCheckbox;
};
} // End of namespace Nancy
#endif // NANCY_DIALOGS_H

View File

@ -24,19 +24,22 @@
#include "engines/nancy/nancy.h"
#include "engines/nancy/input.h"
#include "engines/nancy/dialogs.h"
class NancyMetaEngine : public AdvancedMetaEngine {
public:
const char *getName() const override {
virtual const char *getName() const override {
return "nancy";
}
bool hasFeature(MetaEngineFeature f) const override;
Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const override;
virtual bool hasFeature(MetaEngineFeature f) const override;
virtual Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const override;
int getMaximumSaveSlot() const override;
virtual int getMaximumSaveSlot() const override;
Common::KeymapArray initKeymaps(const char *target) const override;
virtual Common::KeymapArray initKeymaps(const char *target) const override;
virtual GUI::OptionsContainerWidget *buildEngineOptionsWidgetDynamic(GUI::GuiObject *boss, const Common::String &name, const Common::String &target) const override;
};
Common::KeymapArray NancyMetaEngine::initKeymaps(const char *target) const {
@ -71,6 +74,10 @@ Common::Error NancyMetaEngine::createInstance(OSystem *syst, Engine **engine, co
int NancyMetaEngine::getMaximumSaveSlot() const { return 8; }
GUI::OptionsContainerWidget *NancyMetaEngine::buildEngineOptionsWidgetDynamic(GUI::GuiObject *boss, const Common::String &name, const Common::String &target) const {
return new Nancy::NancyOptionsWidget(boss, name, target);
}
#if PLUGIN_ENABLED_DYNAMIC(NANCY)
REGISTER_PLUGIN_DYNAMIC(NANCY, PLUGIN_TYPE_ENGINE, NancyMetaEngine);
#else

View File

@ -31,6 +31,7 @@ MODULE_OBJS = \
console.o \
cursor.o \
decompress.o \
dialogs.o \
font.o \
graphics.o \
iff.o \

View File

@ -118,7 +118,11 @@ bool NancyEngine::canSaveGameStateCurrently() {
}
bool NancyEngine::hasFeature(EngineFeature f) const {
return (f == kSupportsReturnToLauncher) || (f == kSupportsLoadingDuringRuntime) || (f == kSupportsSavingDuringRuntime);
return (f == kSupportsReturnToLauncher) ||
(f == kSupportsLoadingDuringRuntime) ||
(f == kSupportsSavingDuringRuntime) ||
(f == kSupportsChangingOptionsDuringRuntime) ||
(f == kSupportsSubtitleOptions);
}
const char *NancyEngine::getCopyrightString() const {
@ -279,6 +283,10 @@ void NancyEngine::bootGameEngine() {
SearchMan.addSubDirectoryMatching(gameDataDir, "art");
SearchMan.addSubDirectoryMatching(gameDataDir, "font");
// Register default settings
ConfMan.registerDefault("player_speech", true);
ConfMan.registerDefault("character_speech", true);
// Load archive
Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember("data1.cab");
if (stream) {