From ca29fc0babe8fc985a9e4656f80fc7faec4ac8a5 Mon Sep 17 00:00:00 2001 From: manuel Date: Wed, 11 May 2011 17:38:29 +0200 Subject: - fix audio plugin and make that a real interface - that fixes a duplicate statis audiomanager (1x pacman, 1x audio plugin) on windows - display won/lost dialog upon gameend --- pacman-c++/common/actor.cpp | 6 +- pacman-c++/common/audio.cpp | 109 ++++++++++++++++++++++++------------- pacman-c++/common/audio.h | 96 +++++++------------------------- pacman-c++/common/audiointerface.h | 60 ++++++++++++++++++++ pacman-c++/common/common.pro | 3 +- pacman-c++/common/constants.h | 1 + pacman-c++/common/sceneholder.cpp | 60 ++++++++++++-------- pacman-c++/common/sceneholder.h | 8 ++- 8 files changed, 202 insertions(+), 141 deletions(-) create mode 100644 pacman-c++/common/audiointerface.h (limited to 'pacman-c++/common') diff --git a/pacman-c++/common/actor.cpp b/pacman-c++/common/actor.cpp index 83a54e3..de8d77e 100644 --- a/pacman-c++/common/actor.cpp +++ b/pacman-c++/common/actor.cpp @@ -296,21 +296,21 @@ void Actor::die() setZValue(zValue() * 10); m_dieing->start(); if (m_local) - AudioManager::self()->audioPlayer()->play(Sound::Die); + AudioManager::self()->play(Sound::Die); } void Actor::eatingFruit() { if (!m_local) return; - AudioManager::self()->audioPlayer()->play(Sound::EatingFruit); + AudioManager::self()->play(Sound::EatingFruit); } void Actor::eatingPacman() { if (!m_local) return; - AudioManager::self()->audioPlayer()->play(Sound::EatingGhost); + AudioManager::self()->play(Sound::EatingGhost); } void Actor::startEating() diff --git a/pacman-c++/common/audio.cpp b/pacman-c++/common/audio.cpp index d29303d..eddbace 100644 --- a/pacman-c++/common/audio.cpp +++ b/pacman-c++/common/audio.cpp @@ -23,7 +23,7 @@ AudioManager::AudioManager() } preload(); - if (!tryLoadPhononPlugin()) + if (!tryLoadAudioPlugin("*phononplayer*")) { qWarning() << "Unable to load audio plugin. Audio disabled.."; m_players.append(new NoopAudioPlayer(this)); @@ -31,6 +31,7 @@ AudioManager::AudioManager() } AudioPlayer *firstplayer = m_factory->create(this); + firstplayer->setWorking(m_working); firstplayer->test(m_sounds[Sound::EatingFruit], Sound::length[Sound::EatingFruit] * 2); m_working = firstplayer->isWorking(); m_players.append(firstplayer); @@ -118,6 +119,33 @@ void AudioManager::unregisterAudioPlayer(AudioPlayer *player) m_players.removeAll(player); } + +void AudioManager::unregisterAudioPlayer_helper(QObject *player) +{ + unregisterAudioPlayer(static_cast(player)); +} + +void AudioManager::play(Sound::Type sound, AudioPlayer *player) +{ + if (player == NULL) + player = audioPlayer(); + player->play(this->sound(sound), length(sound)); +} + +void AudioManager::setSource(Sound::Type sound, AudioPlayer *player) +{ + if (player == NULL) + player = audioPlayer(); + player->setSource(this->sound(sound), length(sound)); +} + +void AudioManager::enqueue(Sound::Type sound, AudioPlayer *player) +{ + if (player == NULL) + player = audioPlayer(); + player->enqueue(this->sound(sound), length(sound)); +} + QFile *AudioManager::sound(Sound::Type sound) { if (!isWorking()) @@ -125,9 +153,9 @@ QFile *AudioManager::sound(Sound::Type sound) return m_sounds.at(sound); } -void AudioManager::unregisterAudioPlayer_helper(QObject *player) +unsigned int AudioManager::length(Sound::Type sound) { - unregisterAudioPlayer(static_cast(player)); + return Sound::length[sound]; } void AudioManager::preload() @@ -137,13 +165,14 @@ void AudioManager::preload() Q_ASSERT(sounds.count() > 0); for(unsigned i = 1; i <= sounds.count(); ++i) m_sounds.append(new QFile(QString(":/sound/sound%1").arg(i), this)); + Q_ASSERT(m_sounds.count() != (sizeof(Sound::length) / sizeof(unsigned int))); } -bool AudioManager::tryLoadPhononPlugin() +bool AudioManager::tryLoadAudioPlugin(const QString &libraryname) { QDir dir = qApp->applicationDirPath(); QStringList filters; - filters << "*phononplayer*"; + filters << libraryname; foreach (QString file, dir.entryList(filters, QDir::Files)) { file = dir.absoluteFilePath(file); @@ -163,25 +192,19 @@ bool AudioManager::tryLoadPhononPlugin() return false; } -AudioPlayer *AudioManager::createAudioPlayer() +AudioPlayer *AudioManager::createAudioPlayer(QObject *parent) { if (m_factory == NULL) return NULL; - AudioPlayer *player = m_factory->create(this); + AudioPlayer *player = m_factory->create(parent != NULL ? parent : this); + player->setWorking(m_working); registerAudioPlayer(player); return player; } /* --------------------------------------------------------------- */ -AudioPlayer *NoopAudioPlayerFactory::create(QObject *parent) -{ - return new FakeAudioPlayer(parent); -} - -/* --------------------------------------------------------------- */ - NoopAudioPlayer::NoopAudioPlayer(QObject *parent) : AudioPlayer(parent), m_working(false), m_muted(false), m_playing(false), m_paused(false) {} @@ -209,19 +232,6 @@ void NoopAudioPlayer::play() m_playing = false; } -void NoopAudioPlayer::play(Sound::Type /* sound */) -{ - play(); -} - -bool NoopAudioPlayer::isPlaying() -{ - return m_playing; -} - -void NoopAudioPlayer::enqueue(Sound::Type /* sound */) -{} - void NoopAudioPlayer::pause() { m_paused = true; @@ -258,7 +268,32 @@ void NoopAudioPlayer::prefinishMarkReached_ex(qint32 mark) emit prefinishMarkReached(mark); } -void NoopAudioPlayer::test(QFile * /* testsound */, qint32 /* length */) +void NoopAudioPlayer::seek(qint64 /* time */) +{} + +void NoopAudioPlayer::setWorking(bool working) +{ + m_working = working; +} + +void NoopAudioPlayer::test(QFile * /* sound */, unsigned int /* length */) +{} + +void NoopAudioPlayer::play(QFile *sound, unsigned int length) +{ + setSource(sound, length); + play(); +} + +void NoopAudioPlayer::setSource(QFile * /* sound */, unsigned int /* length */) +{} + +bool NoopAudioPlayer::isPlaying() +{ + return m_playing; +} + +void NoopAudioPlayer::enqueue(QFile * /* sound */, unsigned int /* length */) {} /* --------------------------------------------------------------- */ @@ -270,13 +305,13 @@ FakeAudioPlayer::FakeAudioPlayer(QObject *parent) connect(&m_timer, SIGNAL(timeout()), this, SLOT(finished_ex())); } -void FakeAudioPlayer::play(Sound::Type sound) +void FakeAudioPlayer::play(QFile * /* sound */, unsigned int length) { m_playing = true; m_paused = false; m_timer.setSingleShot(true); - unsigned int interval = Sound::length[sound]; + unsigned int interval = length; /* add a small delay server side only */ if (Constants::server) interval += Constants::tick; @@ -299,17 +334,15 @@ GaplessAudioPlayer::GaplessAudioPlayer(Sound::Type sound, qint32 mark, QObject * if (!m_working) return; - m_player1 = AudioManager::self()->createAudioPlayer(); - m_player2 = AudioManager::self()->createAudioPlayer(); + m_player1 = AudioManager::self()->createAudioPlayer(this); + m_player2 = AudioManager::self()->createAudioPlayer(this); + /* this doesn't work reliable on all platforms (e.g. windows) */ m_player2->setPrefinishMark(mark); m_player1->setPrefinishMark(mark); connect(m_player1, SIGNAL(prefinishMarkReached(qint32)), this, SLOT(startPlayer2())); connect(m_player2, SIGNAL(prefinishMarkReached(qint32)), this, SLOT(startPlayer1())); - - AudioManager::self()->registerAudioPlayer(m_player1); - AudioManager::self()->registerAudioPlayer(m_player2); } bool GaplessAudioPlayer::isWorking() const @@ -350,10 +383,12 @@ void GaplessAudioPlayer::pause() void GaplessAudioPlayer::startPlayer1() { - m_player1->play(m_sound); + AudioManager::self()->play(m_sound, m_player1); + m_player2->pause(); } void GaplessAudioPlayer::startPlayer2() { - m_player2->play(m_sound); + AudioManager::self()->play(m_sound, m_player2); + m_player1->pause(); } diff --git a/pacman-c++/common/audio.h b/pacman-c++/common/audio.h index bc7d66e..45af34b 100644 --- a/pacman-c++/common/audio.h +++ b/pacman-c++/common/audio.h @@ -1,6 +1,7 @@ #ifndef AUDIO_H #define AUDIO_H +#include "audiointerface.h" #include #include #include @@ -19,52 +20,12 @@ namespace Sound }; const unsigned int length[] = { - 4310, 2090, 570, 570, 1720, + 4310, 2090, 570, 570, 1720, 1990 }; }; /* --------------------------------------------------------------- */ -class AudioPlayer - : public QObject -{ - Q_OBJECT - friend class AudioManager; - -public: - AudioPlayer(QObject *parent = 0) - : QObject(parent) - {} - virtual ~AudioPlayer() - {} - virtual bool isWorking() const = 0; - virtual void setMuted(bool mute = true) = 0; - virtual bool isMuted() const = 0; - virtual void play() = 0; - virtual void play(Sound::Type sound) = 0; - virtual bool isPlaying() = 0; - virtual void enqueue(Sound::Type sound) = 0; - virtual void pause() = 0; - virtual bool isPaused() = 0; - virtual void stop() = 0; - virtual bool isStopped() = 0; - virtual void clear() = 0; - virtual void clearQueue() = 0; - virtual void setPrefinishMark(qint32 msecToEnd) = 0; - -protected slots: - virtual void prefinishMarkReached_ex(qint32 mark) = 0; - -signals: - void finished(); - void prefinishMarkReached(qint32 mark); - -protected: - virtual void test(QFile *testsound, qint32 length) = 0; -}; - -/* --------------------------------------------------------------- */ - class NoopAudioPlayer : public AudioPlayer { @@ -72,14 +33,11 @@ class NoopAudioPlayer friend class AudioManager; public: - NoopAudioPlayer(QObject *parent = 0); virtual bool isWorking() const; virtual void setMuted(bool mute = true); virtual bool isMuted() const; virtual void play(); - virtual void play(Sound::Type sound); virtual bool isPlaying(); - virtual void enqueue(Sound::Type sound); virtual void pause(); virtual bool isPaused(); virtual void stop(); @@ -87,13 +45,19 @@ public: virtual void clear(); virtual void clearQueue(); virtual void setPrefinishMark(qint32 msecToEnd); + virtual void seek(qint64 time); + +protected: + NoopAudioPlayer(QObject *parent = 0); + virtual void setWorking(bool working = true); + virtual void test(QFile *sound, unsigned int length); + virtual void play(QFile *sound, unsigned int length); + virtual void setSource(QFile *sound, unsigned int length); + virtual void enqueue(QFile *sound, unsigned int length); protected slots: virtual void prefinishMarkReached_ex(qint32 mark); -protected: - virtual void test(QFile *testsound, qint32 length); - protected: bool m_working; bool m_muted; @@ -109,9 +73,9 @@ class FakeAudioPlayer Q_OBJECT friend class AudioManager; -public: +protected: FakeAudioPlayer(QObject *parent = 0); - virtual void play(Sound::Type sound); + virtual void play(QFile *sound, unsigned int length); protected slots: void finished_ex(); @@ -148,27 +112,6 @@ protected: /* --------------------------------------------------------------- */ -class AudioPlayerFactory -{ -public: - virtual ~AudioPlayerFactory() - {} - virtual AudioPlayer *create(QObject *parent = 0) = 0; -}; - -Q_DECLARE_INTERFACE(AudioPlayerFactory, "at.ac.tuwien.foop.pacman.AudioPlayerFactory/1.0"); - -/* --------------------------------------------------------------- */ - -class NoopAudioPlayerFactory - : public AudioPlayerFactory -{ -public: - virtual AudioPlayer *create(QObject *parent = 0); -}; - -/* --------------------------------------------------------------- */ - class AudioManager : public QObject { @@ -189,8 +132,9 @@ public: AudioPlayer *audioPlayer(); void registerAudioPlayer(AudioPlayer *player); void unregisterAudioPlayer(AudioPlayer *player); - - QFile *sound(Sound::Type sound); + void play(Sound::Type sound, AudioPlayer *player = NULL); + void setSource(Sound::Type sound, AudioPlayer *player = NULL); + void enqueue(Sound::Type sound, AudioPlayer *player = NULL); signals: void mutedChanged(bool muted); @@ -200,8 +144,10 @@ private slots: protected: void preload(); - bool tryLoadPhononPlugin(); - AudioPlayer *createAudioPlayer(); + bool tryLoadAudioPlugin(const QString &libraryname); + AudioPlayer *createAudioPlayer(QObject *parent = 0); + QFile *sound(Sound::Type sound); + unsigned int length(Sound::Type sound); private: bool m_muted; @@ -212,4 +158,4 @@ private: AudioPlayerFactory *m_factory; }; -#endif // AUDIOPLAYER_H +#endif // AUDIO_H diff --git a/pacman-c++/common/audiointerface.h b/pacman-c++/common/audiointerface.h new file mode 100644 index 0000000..66679b6 --- /dev/null +++ b/pacman-c++/common/audiointerface.h @@ -0,0 +1,60 @@ +#ifndef AUDIOINTERFACE_H +#define AUDIOINTERFACE_H + +#include +#include + +class AudioPlayer + : public QObject +{ + Q_OBJECT + friend class AudioManager; + +public: + virtual ~AudioPlayer() + {} + virtual bool isWorking() const = 0; + virtual void setMuted(bool mute = true) = 0; + virtual bool isMuted() const = 0; + virtual void play() = 0; + virtual bool isPlaying() = 0; + virtual void pause() = 0; + virtual bool isPaused() = 0; + virtual void stop() = 0; + virtual bool isStopped() = 0; + virtual void clear() = 0; + virtual void clearQueue() = 0; + virtual void setPrefinishMark(qint32 msecToEnd) = 0; + virtual void seek(qint64 time) = 0; + +signals: + void finished(); + void prefinishMarkReached(qint32 mark); + +protected: + AudioPlayer(QObject *parent = 0) + : QObject(parent) + {} + virtual void setWorking(bool working = true) = 0; + virtual void test(QFile *sound, unsigned int length) = 0; + virtual void play(QFile *sound, unsigned int length) = 0; + virtual void setSource(QFile *sound, unsigned int length) = 0; + virtual void enqueue(QFile *sound, unsigned int length) = 0; + +protected slots: + virtual void prefinishMarkReached_ex(qint32 mark) = 0; +}; + +/* --------------------------------------------------------------- */ + +class AudioPlayerFactory +{ +public: + virtual ~AudioPlayerFactory() + {} + virtual AudioPlayer *create(QObject *parent = 0) = 0; +}; + +Q_DECLARE_INTERFACE(AudioPlayerFactory, "at.ac.tuwien.foop.pacman.AudioPlayerFactory/1.0"); + +#endif // AUDIOINTERFACE_H diff --git a/pacman-c++/common/common.pro b/pacman-c++/common/common.pro index 1114e17..39481c0 100644 --- a/pacman-c++/common/common.pro +++ b/pacman-c++/common/common.pro @@ -24,7 +24,8 @@ HEADERS += pixmapitem.h \ audio.h \ sceneholder.h \ util.h \ - gameentity.h + gameentity.h \ + audiointerface.h OTHER_FILES += style.qss \ pacman.rc diff --git a/pacman-c++/common/constants.h b/pacman-c++/common/constants.h index d40c39e..7f32422 100644 --- a/pacman-c++/common/constants.h +++ b/pacman-c++/common/constants.h @@ -22,6 +22,7 @@ namespace Constants { const unsigned int port = 7321; const unsigned int connection_timeout = 3000; const unsigned int packet_timeout = 3000; + const unsigned int recv_interval = Constants::tick / 2; } namespace Game diff --git a/pacman-c++/common/sceneholder.cpp b/pacman-c++/common/sceneholder.cpp index bd9b01b..d429445 100644 --- a/pacman-c++/common/sceneholder.cpp +++ b/pacman-c++/common/sceneholder.cpp @@ -23,7 +23,7 @@ SceneHolder::SceneHolder(QObject *parent) void SceneHolder::reset() { processDelayedItems(); - showEatingText(false); + hideOverlayText(); /* remove actors from scene so they don't get deleted during clear */ foreach(Actor *actor, m_actors) @@ -272,15 +272,22 @@ QList &SceneHolder::eatingOrder() return m_eatingorder; } -void SceneHolder::showEatingText(bool show) +void SceneHolder::hideOverlayText() { - if (!show) - { - if (m_overlayText->scene() == this) - removeItem(m_overlayText); - return; - } + if (m_overlayText->scene() == this) + removeItem(m_overlayText); +} + +void SceneHolder::centerOverlayText(unsigned int lines) +{ + QFontMetrics metrics(m_overlayText->font()); + m_overlayText->setPos((width() - m_overlayText->textWidth()) / 2, (height() - metrics.height() * lines) / 2); + m_overlayText->setZValue(100); +} +void SceneHolder::showEatingText() +{ + hideOverlayText(); m_overlayText->setDefaultTextColor(Qt::black); QString text = QString( "
" @@ -307,23 +314,14 @@ void SceneHolder::showEatingText(bool show) m_overlayText->setHtml(text); m_overlayText->setTextWidth(150); m_overlayText->setOpacity(0.9); - - QFontMetrics metrics(m_overlayText->font()); - m_overlayText->setPos((width() - m_overlayText->textWidth()) / 2, (height() - metrics.height() * lines) / 2); - m_overlayText->setZValue(100); + centerOverlayText(lines); addItem(m_overlayText); } -void SceneHolder::showWaitingForPlayers(bool show) +void SceneHolder::showWaitingForPlayers() { - if (!show) - { - if (m_overlayText->scene() == this) - removeItem(m_overlayText); - return; - } - + hideOverlayText(); m_overlayText->setDefaultTextColor(Qt::black); QString text = QString( "
" @@ -335,10 +333,26 @@ void SceneHolder::showWaitingForPlayers(bool show) m_overlayText->setHtml(text); m_overlayText->setTextWidth(150); m_overlayText->setOpacity(0.9); + centerOverlayText(lines); - QFontMetrics metrics(m_overlayText->font()); - m_overlayText->setPos((width() - m_overlayText->textWidth()) / 2, (height() - metrics.height() * lines) / 2); - m_overlayText->setZValue(100); + addItem(m_overlayText); +} + +void SceneHolder::showWonLost(bool won) +{ + hideOverlayText(); + m_overlayText->setDefaultTextColor(Qt::black); + QString text = QString( + "
" + "
" + "You %1!
" + "
" + ).arg((won) ? "won" : "lost"); + unsigned int lines = 3; + m_overlayText->setHtml(text); + m_overlayText->setTextWidth(150); + m_overlayText->setOpacity(0.9); + centerOverlayText(lines); addItem(m_overlayText); } diff --git a/pacman-c++/common/sceneholder.h b/pacman-c++/common/sceneholder.h index 0872837..801b98b 100644 --- a/pacman-c++/common/sceneholder.h +++ b/pacman-c++/common/sceneholder.h @@ -24,8 +24,12 @@ public: Color::Color color(); void setEatingOrder(QList &order); QList &eatingOrder(); - void showEatingText(bool show = true); - void showWaitingForPlayers(bool show = true); + + void hideOverlayText(); + void centerOverlayText(unsigned int lines); + void showEatingText(); + void showWaitingForPlayers(); + void showWonLost(bool won); signals: void allPointsRemoved(); -- cgit v1.2.3