summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2012-02-18 22:47:30 +0100
committerThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2012-02-18 23:24:03 +0100
commit20afba1adc84dd0e859605250c5a44a111045c2b (patch)
tree304f34e96403215a8e1d9a3cf880a6a28f5a4721 /src
parent6fd1246735010bccd0d75e9e7969431b963b7858 (diff)
downloadmana-20afba1adc84dd0e859605250c5a44a111045c2b.tar.gz
mana-20afba1adc84dd0e859605250c5a44a111045c2b.tar.bz2
mana-20afba1adc84dd0e859605250c5a44a111045c2b.tar.xz
mana-20afba1adc84dd0e859605250c5a44a111045c2b.zip
Added notification sound on receiving whisper
One of the sound channels is reserved for notification sounds, of which the volume can be configured separately. Currently, the only notification sound that is played is for receiving whispers. That can be extended later. The newmessage.ogg sound used currently is the one for receiving a message with the Psi instant messenger. Parts of this patch are based on the new message notification in ManaPlus. Reviewed-by: Erik Schilling
Diffstat (limited to 'src')
-rw-r--r--src/client.cpp3
-rw-r--r--src/client.h9
-rw-r--r--src/defaults.cpp1
-rw-r--r--src/gui/gui.cpp3
-rw-r--r--src/gui/setup_audio.cpp32
-rw-r--r--src/gui/setup_audio.h18
-rw-r--r--src/gui/widgets/chattab.cpp23
-rw-r--r--src/gui/widgets/chattab.h9
-rw-r--r--src/gui/widgets/whispertab.h3
-rw-r--r--src/resources/soundeffect.cpp4
-rw-r--r--src/resources/soundeffect.h3
-rw-r--r--src/sound.cpp29
-rw-r--r--src/sound.h9
13 files changed, 125 insertions, 21 deletions
diff --git a/src/client.cpp b/src/client.cpp
index 5a9cc726..28affce6 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -380,6 +380,7 @@ Client::Client(const Options &options):
sound.init();
sound.setSfxVolume(config.getIntValue("sfxVolume"));
+ sound.setNotificationsVolume(config.getIntValue("notificationsVolume"));
sound.setMusicVolume(config.getIntValue("musicVolume"));
}
catch (const char *err)
@@ -541,7 +542,7 @@ int Client::exec()
lastTickTime = tick_time;
// Update the screen when application is active, delay otherwise.
- if (SDL_GetAppState() & SDL_APPACTIVE)
+ if (isActive())
{
frame_count++;
gui->draw();
diff --git a/src/client.h b/src/client.h
index 2ee6764c..4ad5562d 100644
--- a/src/client.h
+++ b/src/client.h
@@ -214,6 +214,15 @@ public:
*/
void videoResized(int width, int height);
+ static bool isActive()
+ { return SDL_GetAppState() & SDL_APPACTIVE; }
+
+ static bool hasInputFocus()
+ { return SDL_GetAppState() & SDL_APPINPUTFOCUS; }
+
+ static bool hasMouseFocus()
+ { return SDL_GetAppState() & SDL_APPMOUSEFOCUS; }
+
private:
void initRootDir();
void initHomeDir();
diff --git a/src/defaults.cpp b/src/defaults.cpp
index fea7c435..6c75797d 100644
--- a/src/defaults.cpp
+++ b/src/defaults.cpp
@@ -85,6 +85,7 @@ DefaultsData* getConfigDefaults()
AddDEF(configData, "hwaccel", false);
AddDEF(configData, "sound", false);
AddDEF(configData, "sfxVolume", 100);
+ AddDEF(configData, "notificationsVolume", 100);
AddDEF(configData, "musicVolume", 60);
AddDEF(configData, "remember", false);
AddDEF(configData, "username", "");
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp
index 2f24d009..78fc42fb 100644
--- a/src/gui/gui.cpp
+++ b/src/gui/gui.cpp
@@ -29,6 +29,7 @@
#include "gui/widgets/window.h"
#include "gui/widgets/windowcontainer.h"
+#include "client.h"
#include "configuration.h"
#include "eventlistener.h"
#include "graphics.h"
@@ -204,7 +205,7 @@ void Gui::draw()
int mouseX, mouseY;
Uint8 button = SDL_GetMouseState(&mouseX, &mouseY);
- if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS || button & SDL_BUTTON(1))
+ if ((Client::hasMouseFocus() || button & SDL_BUTTON(1))
&& mCustomCursor
&& mMouseCursorAlpha > 0.0f)
{
diff --git a/src/gui/setup_audio.cpp b/src/gui/setup_audio.cpp
index c43210d0..69ee3dc3 100644
--- a/src/gui/setup_audio.cpp
+++ b/src/gui/setup_audio.cpp
@@ -37,31 +37,38 @@
Setup_Audio::Setup_Audio():
mMusicVolume(config.getIntValue("musicVolume")),
mSfxVolume(config.getIntValue("sfxVolume")),
+ mNotificationsVolume(config.getIntValue("notificationsVolume")),
mSoundEnabled(config.getBoolValue("sound")),
mDownloadEnabled(config.getBoolValue("download-music")),
mSoundCheckBox(new CheckBox(_("Sound"), mSoundEnabled)),
mDownloadMusicCheckBox(new CheckBox(_("Download music"), mDownloadEnabled)),
mSfxSlider(new Slider(0, sound.getMaxVolume())),
+ mNotificationsSlider(new Slider(0, sound.getMaxVolume())),
mMusicSlider(new Slider(0, sound.getMaxVolume()))
{
setName(_("Audio"));
setDimension(gcn::Rectangle(0, 0, 250, 200));
gcn::Label *sfxLabel = new Label(_("Sfx volume"));
+ gcn::Label *notificationsLabel = new Label(_("Notifications volume"));
gcn::Label *musicLabel = new Label(_("Music volume"));
mSfxSlider->setActionEventId("sfx");
+ mNotificationsSlider->setActionEventId("notifications");
mMusicSlider->setActionEventId("music");
mSfxSlider->addActionListener(this);
+ mNotificationsSlider->addActionListener(this);
mMusicSlider->addActionListener(this);
mSoundCheckBox->setPosition(10, 10);
mSfxSlider->setValue(mSfxVolume);
+ mNotificationsSlider->setValue(mNotificationsVolume);
mMusicSlider->setValue(mMusicVolume);
mSfxSlider->setWidth(90);
+ mNotificationsSlider->setWidth(90);
mMusicSlider->setWidth(90);
// Do the layout
@@ -71,9 +78,11 @@ Setup_Audio::Setup_Audio():
place(0, 0, mSoundCheckBox);
place(0, 1, mSfxSlider);
place(1, 1, sfxLabel);
- place(0, 2, mMusicSlider);
- place(1, 2, musicLabel);
- place(0, 3, mDownloadMusicCheckBox);
+ place(0, 2, mNotificationsSlider);
+ place(1, 2, notificationsLabel);
+ place(0, 3, mMusicSlider);
+ place(1, 3, musicLabel);
+ place(0, 4, mDownloadMusicCheckBox);
setDimension(gcn::Rectangle(0, 0, 370, 280));
}
@@ -83,6 +92,7 @@ void Setup_Audio::apply()
mSoundEnabled = mSoundCheckBox->isSelected();
mDownloadEnabled = mDownloadMusicCheckBox->isSelected();
mSfxVolume = config.getIntValue("sfxVolume");
+ mNotificationsVolume = config.getIntValue("sfxVolume");
mMusicVolume = config.getIntValue("musicVolume");
config.setValue("sound", mSoundEnabled);
@@ -134,12 +144,20 @@ void Setup_Audio::action(const gcn::ActionEvent &event)
{
if (event.getId() == "sfx")
{
- config.setValue("sfxVolume", (int) mSfxSlider->getValue());
- sound.setSfxVolume((int) mSfxSlider->getValue());
+ int volume = (int) mSfxSlider->getValue();
+ config.setValue("sfxVolume", volume);
+ sound.setSfxVolume(volume);
+ }
+ else if (event.getId() == "notifications")
+ {
+ int volume = (int) mNotificationsSlider->getValue();
+ config.setValue("notificationsVolume", volume);
+ sound.setNotificationsVolume(volume);
}
else if (event.getId() == "music")
{
- config.setValue("musicVolume", (int) mMusicSlider->getValue());
- sound.setMusicVolume((int) mMusicSlider->getValue());
+ int volume = (int) mMusicSlider->getValue();
+ config.setValue("musicVolume", volume);
+ sound.setMusicVolume(volume);
}
}
diff --git a/src/gui/setup_audio.h b/src/gui/setup_audio.h
index 5477eaad..ac81bdb7 100644
--- a/src/gui/setup_audio.h
+++ b/src/gui/setup_audio.h
@@ -39,11 +39,17 @@ class Setup_Audio : public SetupTab, public gcn::ActionListener
void action(const gcn::ActionEvent &event);
private:
- int mMusicVolume, mSfxVolume;
- bool mSoundEnabled, mDownloadEnabled;
-
- gcn::CheckBox *mSoundCheckBox, *mDownloadMusicCheckBox;
- gcn::Slider *mSfxSlider, *mMusicSlider;
+ int mMusicVolume;
+ int mSfxVolume;
+ int mNotificationsVolume;
+ bool mSoundEnabled;
+ bool mDownloadEnabled;
+
+ gcn::CheckBox *mSoundCheckBox;
+ gcn::CheckBox *mDownloadMusicCheckBox;
+ gcn::Slider *mSfxSlider;
+ gcn::Slider *mNotificationsSlider;
+ gcn::Slider *mMusicSlider;
};
-#endif
+#endif // GUI_SETUP_AUDIO_H
diff --git a/src/gui/widgets/chattab.cpp b/src/gui/widgets/chattab.cpp
index 8642be69..1979ecbd 100644
--- a/src/gui/widgets/chattab.cpp
+++ b/src/gui/widgets/chattab.cpp
@@ -23,9 +23,11 @@
#include "actorspritemanager.h"
#include "chatlogger.h"
+#include "client.h"
#include "commandhandler.h"
#include "configuration.h"
#include "localplayer.h"
+#include "sound.h"
#include "gui/gui.h"
#include "gui/recorder.h"
@@ -237,10 +239,20 @@ void ChatTab::chatLog(std::string line, Own own, bool ignoreRecord)
}
mScrollArea->logic();
+
chatWindow->mRecorder->record(line.substr(3));
- if (this != getTabbedArea()->getSelectedTab() &&
- own != BY_PLAYER)
- setFlash(true);
+
+ if (own != BY_PLAYER)
+ {
+ bool currentTab = getTabbedArea()->getSelectedTab() == this;
+
+ if (!currentTab)
+ setFlash(true);
+
+ if (!(currentTab && Client::hasInputFocus()) && own != BY_SERVER)
+ if (checkNotify(own))
+ sound.playNotification("system/newmessage.ogg");
+ }
}
void ChatTab::chatLog(const std::string &nick, const std::string &msg)
@@ -318,6 +330,11 @@ void ChatTab::handleCommand(const std::string &msg)
commandHandler->handleCommand(msg, this);
}
+bool ChatTab::checkNotify(Own own) const
+{
+ return own == ACT_WHISPER;
+}
+
void ChatTab::getAutoCompleteList(std::vector<std::string> &names) const
{
actorSpriteManager->getPlayerNPCNameLister()->getAutoCompleteList(names);
diff --git a/src/gui/widgets/chattab.h b/src/gui/widgets/chattab.h
index 3796c37b..200ad55a 100644
--- a/src/gui/widgets/chattab.h
+++ b/src/gui/widgets/chattab.h
@@ -115,6 +115,15 @@ class ChatTab : public Tab, public AutoCompleteLister, public EventListener
virtual void handleCommand(const std::string &msg);
/**
+ * Returns whether a notify sound may be played for the given type of
+ * message. By default, only returns true for inline whispers.
+ *
+ * Is never called for server-messages or when the window has focus
+ * and this is the current tab.
+ */
+ virtual bool checkNotify(Own own) const;
+
+ /**
* Adapts the text format to the current gui opacity,
* for better readability.
*/
diff --git a/src/gui/widgets/whispertab.h b/src/gui/widgets/whispertab.h
index e88d084b..a0dcfc14 100644
--- a/src/gui/widgets/whispertab.h
+++ b/src/gui/widgets/whispertab.h
@@ -57,6 +57,9 @@ class WhisperTab : public ChatTab
void handleCommand(const std::string &msg);
+ bool checkNotify(Own) const
+ { return true; }
+
private:
std::string mNick;
};
diff --git a/src/resources/soundeffect.cpp b/src/resources/soundeffect.cpp
index 91ee1fde..d1b0227b 100644
--- a/src/resources/soundeffect.cpp
+++ b/src/resources/soundeffect.cpp
@@ -44,9 +44,9 @@ Resource *SoundEffect::load(SDL_RWops *rw)
}
}
-bool SoundEffect::play(int loops, int volume)
+bool SoundEffect::play(int loops, int volume, int channel)
{
Mix_VolumeChunk(mChunk, volume);
- return Mix_PlayChannel(-1, mChunk, loops) != -1;
+ return Mix_PlayChannel(channel, mChunk, loops) != -1;
}
diff --git a/src/resources/soundeffect.h b/src/resources/soundeffect.h
index dee8f551..decc60a0 100644
--- a/src/resources/soundeffect.h
+++ b/src/resources/soundeffect.h
@@ -53,11 +53,12 @@ class SoundEffect : public Resource
*
* @param loops Number of times to repeat the playback.
* @param volume Sample playback volume.
+ * @param channel Sample playback channel.
*
* @return <code>true</code> if the playback started properly
* <code>false</code> otherwise.
*/
- virtual bool play(int loops, int volume);
+ bool play(int loops, int volume, int channel = -1);
protected:
SoundEffect(Mix_Chunk *soundEffect): mChunk(soundEffect) {}
diff --git a/src/sound.cpp b/src/sound.cpp
index e8348a40..1af1f136 100644
--- a/src/sound.cpp
+++ b/src/sound.cpp
@@ -31,6 +31,10 @@
#include "resources/resourcemanager.h"
#include "resources/soundeffect.h"
+enum {
+ CHANNEL_NOTIFICATIONS = 0
+};
+
/**
* This will be set to true, when a music can be freed after a fade out
* Currently used by fadeOutCallBack()
@@ -49,6 +53,7 @@ static void fadeOutCallBack()
Sound::Sound():
mInstalled(false),
mSfxVolume(100),
+ mNotificationsVolume(100),
mMusicVolume(60),
mMusic(NULL)
{
@@ -90,8 +95,10 @@ void Sound::init()
}
Mix_AllocateChannels(16);
+ Mix_ReserveChannels(1); // reserve one channel for notification sounds
Mix_VolumeMusic(mMusicVolume);
Mix_Volume(-1, mSfxVolume);
+ Mix_Volume(CHANNEL_NOTIFICATIONS, mNotificationsVolume);
info();
@@ -154,7 +161,18 @@ void Sound::setSfxVolume(int volume)
mSfxVolume = volume;
if (mInstalled)
+ {
Mix_Volume(-1, mSfxVolume);
+ Mix_Volume(CHANNEL_NOTIFICATIONS, mNotificationsVolume);
+ }
+}
+
+void Sound::setNotificationsVolume(int volume)
+{
+ mNotificationsVolume = volume;
+
+ if (mInstalled)
+ Mix_Volume(CHANNEL_NOTIFICATIONS, mNotificationsVolume);
}
static Music *loadMusic(const std::string &fileName)
@@ -281,6 +299,17 @@ void Sound::playSfx(const std::string &path, int x, int y)
}
}
+void Sound::playNotification(const std::string &path)
+{
+ const std::string fullPath = paths.getValue("sfx", "sfx/") + path;
+
+ ResourceManager *resman = ResourceManager::getInstance();
+ if (SoundEffect *sample = resman->getSoundEffect(fullPath))
+ {
+ sample->play(0, 128, CHANNEL_NOTIFICATIONS);
+ }
+}
+
void Sound::close()
{
if (!mInstalled)
diff --git a/src/sound.h b/src/sound.h
index dd368f84..180bca62 100644
--- a/src/sound.h
+++ b/src/sound.h
@@ -92,6 +92,7 @@ class Sound
void setMusicVolume(int volume);
void setSfxVolume(int volume);
+ void setNotificationsVolume(int volume);
/**
* Plays a sound at the specified location.
@@ -103,6 +104,13 @@ class Sound
void playSfx(const std::string &path, int x = 0, int y = 0);
/**
+ * Plays a sound on the notification channel.
+ *
+ * @param path The resource path to the sound file.
+ */
+ void playNotification(const std::string &path);
+
+ /**
* The sound logic.
* Currently used to check whether the music file can be freed after
* a fade out, and whether new music has to be played.
@@ -125,6 +133,7 @@ class Sound
bool mInstalled;
int mSfxVolume;
+ int mNotificationsVolume;
int mMusicVolume;
std::string mCurrentMusicFile;