summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2011-05-11 17:38:29 +0200
committermanuel <manuel@mausz.at>2011-05-11 17:38:29 +0200
commitca29fc0babe8fc985a9e4656f80fc7faec4ac8a5 (patch)
treefb48f74ffcddcd8b260ebf78062623427aeda862
parent535c342a2f28e0a1e90010b2f0ff4018eeeb200a (diff)
downloadfoop-ca29fc0babe8fc985a9e4656f80fc7faec4ac8a5.tar.gz
foop-ca29fc0babe8fc985a9e4656f80fc7faec4ac8a5.tar.bz2
foop-ca29fc0babe8fc985a9e4656f80fc7faec4ac8a5.zip
- 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
-rw-r--r--pacman-c++/client/client.cpp14
-rw-r--r--pacman-c++/client/mainwidget.cpp95
-rw-r--r--pacman-c++/client/mainwidget.h7
-rw-r--r--pacman-c++/common.pri4
-rw-r--r--pacman-c++/common/actor.cpp6
-rw-r--r--pacman-c++/common/audio.cpp109
-rw-r--r--pacman-c++/common/audio.h96
-rw-r--r--pacman-c++/common/audiointerface.h60
-rw-r--r--pacman-c++/common/common.pro3
-rw-r--r--pacman-c++/common/constants.h1
-rw-r--r--pacman-c++/common/sceneholder.cpp60
-rw-r--r--pacman-c++/common/sceneholder.h8
-rw-r--r--pacman-c++/phononplayer/phononplayer.cpp37
-rw-r--r--pacman-c++/phononplayer/phononplayer.h14
-rw-r--r--pacman-c++/phononplayer/phononplayer.pro3
-rw-r--r--pacman-c++/proto/pacman.proto4
-rw-r--r--pacman-c++/server/server.cpp39
-rw-r--r--pacman-c++/server/server.h6
18 files changed, 344 insertions, 222 deletions
diff --git a/pacman-c++/client/client.cpp b/pacman-c++/client/client.cpp
index a00249b..d20e6bf 100644
--- a/pacman-c++/client/client.cpp
+++ b/pacman-c++/client/client.cpp
@@ -9,16 +9,14 @@ extern "C" {
9} 9}
10 10
11Client::Client() 11Client::Client()
12 : m_ambientMuted(false) 12 : m_dialog(NULL), m_ambientMuted(false)
13{ 13{
14 m_settings = new QSettings(qApp->organizationName(), qApp->applicationName(), this); 14 m_settings = new QSettings(qApp->organizationName(), qApp->applicationName(), this);
15 m_dialog = new QDialog(this);
16 m_mainWidget = new MainWidget(this); 15 m_mainWidget = new MainWidget(this);
17 createMenu(); 16 createMenu();
18 m_mainWidget->setAmbientMuted(m_ambientMuted); 17 m_mainWidget->setAmbientMuted(m_ambientMuted);
19 setCentralWidget(m_mainWidget); 18 setCentralWidget(m_mainWidget);
20 showConnectDialog(); 19 showConnectDialog();
21 m_dialog->setFocus();
22} 20}
23 21
24void Client::createMenu() 22void Client::createMenu()
@@ -81,6 +79,7 @@ void Client::createMenu()
81 disconnectAction->setDisabled(true); 79 disconnectAction->setDisabled(true);
82 fileMenu->addAction(disconnectAction); 80 fileMenu->addAction(disconnectAction);
83 connect(disconnectAction, SIGNAL(triggered()), m_mainWidget, SLOT(doDisconnect())); 81 connect(disconnectAction, SIGNAL(triggered()), m_mainWidget, SLOT(doDisconnect()));
82 connect(disconnectAction, SIGNAL(triggered()), m_mainWidget, SLOT(deleteGUI()));
84 connect(m_mainWidget, SIGNAL(connected(bool)), disconnectAction, SLOT(setEnabled(bool))); 83 connect(m_mainWidget, SIGNAL(connected(bool)), disconnectAction, SLOT(setEnabled(bool)));
85 84
86 /* exit entry */ 85 /* exit entry */
@@ -134,10 +133,8 @@ QPixmap Client::soundIcon(bool enabled) const
134void Client::showAbout() 133void Client::showAbout()
135{ 134{
136 if (m_dialog != NULL) 135 if (m_dialog != NULL)
137 {
138 delete m_dialog; 136 delete m_dialog;
139 m_dialog = new QDialog(this); 137 m_dialog = new QDialog(this);
140 }
141 m_dialog->setWindowTitle("About Pacman"); 138 m_dialog->setWindowTitle("About Pacman");
142 m_dialog->setWindowFlags(m_dialog->windowFlags() & ~Qt::WindowContextHelpButtonHint); 139 m_dialog->setWindowFlags(m_dialog->windowFlags() & ~Qt::WindowContextHelpButtonHint);
143 140
@@ -176,10 +173,9 @@ void Client::showAbout()
176void Client::showConnectDialog() 173void Client::showConnectDialog()
177{ 174{
178 if (m_dialog != NULL) 175 if (m_dialog != NULL)
179 {
180 delete m_dialog; 176 delete m_dialog;
181 m_dialog = new QDialog(this); 177 m_dialog = new QDialog(this);
182 } 178 m_dialog->setModal(true);
183 m_dialog->setWindowTitle("Connect"); 179 m_dialog->setWindowTitle("Connect");
184 180
185 QGridLayout *layout = new QGridLayout(m_dialog); 181 QGridLayout *layout = new QGridLayout(m_dialog);
diff --git a/pacman-c++/client/mainwidget.cpp b/pacman-c++/client/mainwidget.cpp
index f2e3f46..99b0f5b 100644
--- a/pacman-c++/client/mainwidget.cpp
+++ b/pacman-c++/client/mainwidget.cpp
@@ -22,13 +22,14 @@ MainWidget::MainWidget(QWidget *parent)
22 m_ambientPlayer = new GaplessAudioPlayer(Sound::Ambient, 100, this); 22 m_ambientPlayer = new GaplessAudioPlayer(Sound::Ambient, 100, this);
23 23
24 m_recvTimer = new QTimer(this); 24 m_recvTimer = new QTimer(this);
25 m_recvTimer->setInterval(Constants::tick / 2); 25 m_recvTimer->setInterval(Constants::Networking::recv_interval);
26 connect(m_recvTimer, SIGNAL(timeout()), this, SLOT(tick())); 26 connect(m_recvTimer, SIGNAL(timeout()), this, SLOT(readServerUpdates()));
27} 27}
28 28
29MainWidget::~MainWidget() 29MainWidget::~MainWidget()
30{ 30{
31 doDisconnect(); 31 doDisconnect();
32 deleteGUI();
32 if (m_host != NULL) 33 if (m_host != NULL)
33 { 34 {
34 enet_host_destroy(m_host); 35 enet_host_destroy(m_host);
@@ -38,6 +39,10 @@ MainWidget::~MainWidget()
38 39
39void MainWidget::doConnect(QString srv, unsigned int port) 40void MainWidget::doConnect(QString srv, unsigned int port)
40{ 41{
42 /* preload sound - this eliminates some loading gap on slower computers */
43 AudioManager::self()->setSource(Sound::Intro);
44 deleteGUI();
45
41 Color::Color color = connectToServer(srv, port); 46 Color::Color color = connectToServer(srv, port);
42 if (color == Color::none) 47 if (color == Color::none)
43 { 48 {
@@ -48,7 +53,7 @@ void MainWidget::doConnect(QString srv, unsigned int port)
48 /* create our scene */ 53 /* create our scene */
49 m_scene = new SceneHolder(this); 54 m_scene = new SceneHolder(this);
50 m_scene->setColor(color); 55 m_scene->setColor(color);
51 m_scene->showWaitingForPlayers(true); 56 m_scene->showWaitingForPlayers();
52 createGui(); 57 createGui();
53 58
54 m_recvTimer->start(); 59 m_recvTimer->start();
@@ -77,13 +82,26 @@ void MainWidget::deleteLayout(QLayout *layout)
77 delete layout; 82 delete layout;
78} 83}
79 84
85void MainWidget::deleteGUI()
86{
87 deleteLayout(layout());
88 m_playerScoreLayouts.clear();
89}
90
80void MainWidget::doDisconnect() 91void MainWidget::doDisconnect()
81{ 92{
93 if (!connected())
94 return;
95 closeENetPeer();
96 onDisconnect();
97}
98
99void MainWidget::onDisconnect()
100{
82 stopGame(); 101 stopGame();
83 m_recvTimer->stop(); 102 m_recvTimer->stop();
84 closeENetPeer(); 103 m_scene->clear();
85 deleteLayout(layout()); 104 m_scene->showWonLost(didIWinLoose());
86 m_playerScoreLayouts.clear();
87 emit connected(false); 105 emit connected(false);
88} 106}
89 107
@@ -157,6 +175,23 @@ void MainWidget::updateScore(const ProtoBuf::MapUpdate& packet)
157 } 175 }
158} 176}
159 177
178bool MainWidget::didIWinLoose()
179{
180 QGridLayout *score = m_playerScoreLayouts.at(0);
181 QLabel *allPointsLbl = dynamic_cast<QLabel *>(score->itemAtPosition(1, 1)->widget());
182 unsigned long myscore = allPointsLbl->text().toULong();
183
184 for(unsigned i = 1; i < m_maxplayers; ++i)
185 {
186 QGridLayout *score = m_playerScoreLayouts.at(i);
187 QLabel *allPointsLbl = dynamic_cast<QLabel *>(score->itemAtPosition(1, 1)->widget());
188 unsigned long other = allPointsLbl->text().toULong();
189 if (other > myscore)
190 return false;
191 }
192 return true;
193}
194
160Transmission::field_t MainWidget::translateKey(int key) 195Transmission::field_t MainWidget::translateKey(int key)
161{ 196{
162 switch(key) 197 switch(key)
@@ -182,7 +217,7 @@ Transmission::field_t MainWidget::translateKey(int key)
182 } 217 }
183} 218}
184 219
185void MainWidget::tick() 220void MainWidget::readServerUpdates()
186{ 221{
187 ENetEvent event; 222 ENetEvent event;
188 while (enet_host_service(m_host, &event, 1) > 0) 223 while (enet_host_service(m_host, &event, 1) > 0)
@@ -191,10 +226,10 @@ void MainWidget::tick()
191 { 226 {
192 case ENET_EVENT_TYPE_DISCONNECT: 227 case ENET_EVENT_TYPE_DISCONNECT:
193 m_peer = NULL; 228 m_peer = NULL;
194 doDisconnect(); 229 onDisconnect();
195 break; 230 break;
196 case ENET_EVENT_TYPE_RECEIVE: 231 case ENET_EVENT_TYPE_RECEIVE:
197 tick(&event); 232 processServerUpdates(&event);
198 enet_packet_destroy(event.packet); 233 enet_packet_destroy(event.packet);
199 break; 234 break;
200 default: 235 default:
@@ -203,18 +238,22 @@ void MainWidget::tick()
203 } 238 }
204} 239}
205 240
206void MainWidget::tick(ENetEvent *event) 241void MainWidget::processServerUpdates(ENetEvent *event)
207{ 242{
208 QSharedPointer<QByteArray> data = Util::receivePacket(event->packet); 243 QSharedPointer<QByteArray> data = Util::receivePacket(event->packet);
209 bool worked = m_updatepacket.ParseFromArray(data->data(), data->size()); 244 if (!m_updatepacket.ParseFromArray(data->data(), data->size()))
210 Q_ASSERT(worked); 245 {
211 Q_UNUSED(worked); 246 qWarning() << "Invalid update packet from server";
247 return;
248 }
212 249
213 /* eating order data set indicates a new round */ 250 /* eating order data set indicates a new round */
214 if (m_updatepacket.eating_order_size() > 0) 251 if (m_updatepacket.eating_order_size() > 0)
215 { 252 {
216 Q_ASSERT(m_scene != NULL); 253 Q_ASSERT(m_scene != NULL);
217 m_scene->reset(); 254
255 /* stop game */
256 stopGame();
218 257
219 /* fetch eating order */ 258 /* fetch eating order */
220 QList<Color::Color> order; 259 QList<Color::Color> order;
@@ -222,16 +261,13 @@ void MainWidget::tick(ENetEvent *event)
222 order.append(static_cast<Color::Color>(m_updatepacket.eating_order(i) & Transmission::color_mask)); 261 order.append(static_cast<Color::Color>(m_updatepacket.eating_order(i) & Transmission::color_mask));
223 m_scene->setEatingOrder(order); 262 m_scene->setEatingOrder(order);
224 263
225 /* stop game */
226 stopGame();
227
228 /* and restart game */ 264 /* and restart game */
229 QTimer *timer = new QTimer(this); 265 QTimer *timer = new QTimer(this);
230 timer->setSingleShot(true); 266 timer->setSingleShot(true);
231 timer->setInterval(Sound::length[Sound::Intro] + Constants::tick); 267 timer->setInterval(Sound::length[Sound::Intro] + Constants::tick);
232 connect(timer, SIGNAL(timeout()), this, SLOT(startGame())); 268 connect(timer, SIGNAL(timeout()), this, SLOT(startGame()));
233 timer->start(); 269 timer->start();
234 AudioManager::self()->audioPlayer()->play(Sound::Intro); 270 AudioManager::self()->play(Sound::Intro);
235 } 271 }
236 272
237 Transmission::map_t map = Util::createUninitialisedMap(); 273 Transmission::map_t map = Util::createUninitialisedMap();
@@ -250,10 +286,7 @@ void MainWidget::tick(ENetEvent *event)
250 updateScore(m_updatepacket); 286 updateScore(m_updatepacket);
251 287
252 if (m_updatepacket.eating_order_size() > 0) 288 if (m_updatepacket.eating_order_size() > 0)
253 {
254 m_scene->showWaitingForPlayers(false);
255 m_scene->showEatingText(); 289 m_scene->showEatingText();
256 }
257} 290}
258 291
259void MainWidget::keyPressEvent(QKeyEvent* event) 292void MainWidget::keyPressEvent(QKeyEvent* event)
@@ -273,11 +306,13 @@ void MainWidget::keyPressEvent(QKeyEvent* event)
273 306
274void MainWidget::sendKeyUpdate() 307void MainWidget::sendKeyUpdate()
275{ 308{
309 if (!connected())
310 return;
276 if (m_currentKey == Transmission::direction_none) 311 if (m_currentKey == Transmission::direction_none)
277 return; 312 return;
278 qDebug() << "[SendKey] key=" << m_currentKey; 313 qDebug() << "[SendKey] key=" << m_currentKey;
279 ProtoBuf::KeyPressUpdate packet; 314 ProtoBuf::ClientUpdate packet;
280 packet.set_newkey(m_currentKey); 315 packet.set_new_direction(m_currentKey);
281 Util::sendPacket(packet, m_peer, m_host); 316 Util::sendPacket(packet, m_peer, m_host);
282} 317}
283 318
@@ -294,7 +329,7 @@ void MainWidget::keyReleaseEvent(QKeyEvent* event)
294void MainWidget::startGame() 329void MainWidget::startGame()
295{ 330{
296 disconnect(AudioManager::self()->audioPlayer(), NULL, this, SLOT(startGame())); 331 disconnect(AudioManager::self()->audioPlayer(), NULL, this, SLOT(startGame()));
297 m_scene->showEatingText(false); 332 m_scene->hideOverlayText();
298 m_running = true; 333 m_running = true;
299 sendKeyUpdate(); 334 sendKeyUpdate();
300 m_ambientPlayer->play(); 335 m_ambientPlayer->play();
@@ -304,6 +339,7 @@ void MainWidget::stopGame()
304{ 339{
305 m_running = false; 340 m_running = false;
306 m_ambientPlayer->pause(); 341 m_ambientPlayer->pause();
342 m_scene->reset();
307} 343}
308 344
309void MainWidget::setAmbientMuted(bool muted) 345void MainWidget::setAmbientMuted(bool muted)
@@ -348,11 +384,12 @@ Color::Color MainWidget::connectToServer(QString srv, unsigned int port)
348 QSharedPointer<QByteArray> data = Util::receivePacket(event.packet); 384 QSharedPointer<QByteArray> data = Util::receivePacket(event.packet);
349 enet_packet_destroy(event.packet); 385 enet_packet_destroy(event.packet);
350 ProtoBuf::Init packet; 386 ProtoBuf::Init packet;
351 worked = packet.ParseFromArray(data->data(), data->size()); 387 if (packet.ParseFromArray(data->data(), data->size()))
352 Q_ASSERT(worked); 388 {
353 Q_UNUSED(worked); 389 m_maxplayers = packet.maxplayers();
354 m_maxplayers = packet.maxplayers(); 390 return static_cast<Color::Color>(packet.color() & Transmission::color_mask);
355 return static_cast<Color::Color>(packet.color() & Transmission::color_mask); 391 }
392 qWarning() << "Invalid initialize packet from server";
356 } 393 }
357 } 394 }
358 enet_peer_reset(m_peer); 395 enet_peer_reset(m_peer);
diff --git a/pacman-c++/client/mainwidget.h b/pacman-c++/client/mainwidget.h
index 99ff7d7..cfc6cf8 100644
--- a/pacman-c++/client/mainwidget.h
+++ b/pacman-c++/client/mainwidget.h
@@ -28,6 +28,8 @@ public:
28public slots: 28public slots:
29 void doConnect(QString srv = "127.0.0.1", unsigned int port = Constants::Networking::port); 29 void doConnect(QString srv = "127.0.0.1", unsigned int port = Constants::Networking::port);
30 void doDisconnect(); 30 void doDisconnect();
31 void onDisconnect();
32 void deleteGUI();
31 33
32protected: 34protected:
33 /* handling of current key */ 35 /* handling of current key */
@@ -41,14 +43,15 @@ private slots:
41 void startGame(); 43 void startGame();
42 void stopGame(); 44 void stopGame();
43 void playerScoreClicked(); 45 void playerScoreClicked();
44 void tick(); 46 void readServerUpdates();
45 void tick(ENetEvent *event); 47 void processServerUpdates(ENetEvent *event);
46 void sendKeyUpdate(); 48 void sendKeyUpdate();
47 49
48private: 50private:
49 void createGui(); 51 void createGui();
50 void createMenu(); 52 void createMenu();
51 void updateScore(const ProtoBuf::MapUpdate&); 53 void updateScore(const ProtoBuf::MapUpdate&);
54 bool didIWinLoose();
52 bool isRunning(); 55 bool isRunning();
53 Color::Color connectToServer(QString srv = "127.0.0.1", unsigned int port = Constants::Networking::port); 56 Color::Color connectToServer(QString srv = "127.0.0.1", unsigned int port = Constants::Networking::port);
54 void closeENetPeer(); 57 void closeENetPeer();
diff --git a/pacman-c++/common.pri b/pacman-c++/common.pri
index 38e5c72..eace634 100644
--- a/pacman-c++/common.pri
+++ b/pacman-c++/common.pri
@@ -16,10 +16,6 @@ contains(TEMPLATE, app) {
16 #win32:LIBS += -lws2_32 -lwinmm 16 #win32:LIBS += -lws2_32 -lwinmm
17} 17}
18 18
19contains(CONFIG, plugin) {
20 LIBS += -L.. -lcommon
21}
22
23CONFIG(release, debug|release) { 19CONFIG(release, debug|release) {
24 DEFINES += QT_NO_DEBUG_OUTPUT 20 DEFINES += QT_NO_DEBUG_OUTPUT
25} 21}
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()
296 setZValue(zValue() * 10); 296 setZValue(zValue() * 10);
297 m_dieing->start(); 297 m_dieing->start();
298 if (m_local) 298 if (m_local)
299 AudioManager::self()->audioPlayer()->play(Sound::Die); 299 AudioManager::self()->play(Sound::Die);
300} 300}
301 301
302void Actor::eatingFruit() 302void Actor::eatingFruit()
303{ 303{
304 if (!m_local) 304 if (!m_local)
305 return; 305 return;
306 AudioManager::self()->audioPlayer()->play(Sound::EatingFruit); 306 AudioManager::self()->play(Sound::EatingFruit);
307} 307}
308 308
309void Actor::eatingPacman() 309void Actor::eatingPacman()
310{ 310{
311 if (!m_local) 311 if (!m_local)
312 return; 312 return;
313 AudioManager::self()->audioPlayer()->play(Sound::EatingGhost); 313 AudioManager::self()->play(Sound::EatingGhost);
314} 314}
315 315
316void Actor::startEating() 316void 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()
23 } 23 }
24 24
25 preload(); 25 preload();
26 if (!tryLoadPhononPlugin()) 26 if (!tryLoadAudioPlugin("*phononplayer*"))
27 { 27 {
28 qWarning() << "Unable to load audio plugin. Audio disabled.."; 28 qWarning() << "Unable to load audio plugin. Audio disabled..";
29 m_players.append(new NoopAudioPlayer(this)); 29 m_players.append(new NoopAudioPlayer(this));
@@ -31,6 +31,7 @@ AudioManager::AudioManager()
31 } 31 }
32 32
33 AudioPlayer *firstplayer = m_factory->create(this); 33 AudioPlayer *firstplayer = m_factory->create(this);
34 firstplayer->setWorking(m_working);
34 firstplayer->test(m_sounds[Sound::EatingFruit], Sound::length[Sound::EatingFruit] * 2); 35 firstplayer->test(m_sounds[Sound::EatingFruit], Sound::length[Sound::EatingFruit] * 2);
35 m_working = firstplayer->isWorking(); 36 m_working = firstplayer->isWorking();
36 m_players.append(firstplayer); 37 m_players.append(firstplayer);
@@ -118,6 +119,33 @@ void AudioManager::unregisterAudioPlayer(AudioPlayer *player)
118 m_players.removeAll(player); 119 m_players.removeAll(player);
119} 120}
120 121
122
123void AudioManager::unregisterAudioPlayer_helper(QObject *player)
124{
125 unregisterAudioPlayer(static_cast<AudioPlayer *>(player));
126}
127
128void AudioManager::play(Sound::Type sound, AudioPlayer *player)
129{
130 if (player == NULL)
131 player = audioPlayer();
132 player->play(this->sound(sound), length(sound));
133}
134
135void AudioManager::setSource(Sound::Type sound, AudioPlayer *player)
136{
137 if (player == NULL)
138 player = audioPlayer();
139 player->setSource(this->sound(sound), length(sound));
140}
141
142void AudioManager::enqueue(Sound::Type sound, AudioPlayer *player)
143{
144 if (player == NULL)
145 player = audioPlayer();
146 player->enqueue(this->sound(sound), length(sound));
147}
148
121QFile *AudioManager::sound(Sound::Type sound) 149QFile *AudioManager::sound(Sound::Type sound)
122{ 150{
123 if (!isWorking()) 151 if (!isWorking())
@@ -125,9 +153,9 @@ QFile *AudioManager::sound(Sound::Type sound)
125 return m_sounds.at(sound); 153 return m_sounds.at(sound);
126} 154}
127 155
128void AudioManager::unregisterAudioPlayer_helper(QObject *player) 156unsigned int AudioManager::length(Sound::Type sound)
129{ 157{
130 unregisterAudioPlayer(static_cast<AudioPlayer *>(player)); 158 return Sound::length[sound];
131} 159}
132 160
133void AudioManager::preload() 161void AudioManager::preload()
@@ -137,13 +165,14 @@ void AudioManager::preload()
137 Q_ASSERT(sounds.count() > 0); 165 Q_ASSERT(sounds.count() > 0);
138 for(unsigned i = 1; i <= sounds.count(); ++i) 166 for(unsigned i = 1; i <= sounds.count(); ++i)
139 m_sounds.append(new QFile(QString(":/sound/sound%1").arg(i), this)); 167 m_sounds.append(new QFile(QString(":/sound/sound%1").arg(i), this));
168 Q_ASSERT(m_sounds.count() != (sizeof(Sound::length) / sizeof(unsigned int)));
140} 169}
141 170
142bool AudioManager::tryLoadPhononPlugin() 171bool AudioManager::tryLoadAudioPlugin(const QString &libraryname)
143{ 172{
144 QDir dir = qApp->applicationDirPath(); 173 QDir dir = qApp->applicationDirPath();
145 QStringList filters; 174 QStringList filters;
146 filters << "*phononplayer*"; 175 filters << libraryname;
147 foreach (QString file, dir.entryList(filters, QDir::Files)) 176 foreach (QString file, dir.entryList(filters, QDir::Files))
148 { 177 {
149 file = dir.absoluteFilePath(file); 178 file = dir.absoluteFilePath(file);
@@ -163,25 +192,19 @@ bool AudioManager::tryLoadPhononPlugin()
163 return false; 192 return false;
164} 193}
165 194
166AudioPlayer *AudioManager::createAudioPlayer() 195AudioPlayer *AudioManager::createAudioPlayer(QObject *parent)
167{ 196{
168 if (m_factory == NULL) 197 if (m_factory == NULL)
169 return NULL; 198 return NULL;
170 199
171 AudioPlayer *player = m_factory->create(this); 200 AudioPlayer *player = m_factory->create(parent != NULL ? parent : this);
201 player->setWorking(m_working);
172 registerAudioPlayer(player); 202 registerAudioPlayer(player);
173 return player; 203 return player;
174} 204}
175 205
176/* --------------------------------------------------------------- */ 206/* --------------------------------------------------------------- */
177 207
178AudioPlayer *NoopAudioPlayerFactory::create(QObject *parent)
179{
180 return new FakeAudioPlayer(parent);
181}
182
183/* --------------------------------------------------------------- */
184
185NoopAudioPlayer::NoopAudioPlayer(QObject *parent) 208NoopAudioPlayer::NoopAudioPlayer(QObject *parent)
186 : AudioPlayer(parent), m_working(false), m_muted(false), m_playing(false), m_paused(false) 209 : AudioPlayer(parent), m_working(false), m_muted(false), m_playing(false), m_paused(false)
187{} 210{}
@@ -209,19 +232,6 @@ void NoopAudioPlayer::play()
209 m_playing = false; 232 m_playing = false;
210} 233}
211 234
212void NoopAudioPlayer::play(Sound::Type /* sound */)
213{
214 play();
215}
216
217bool NoopAudioPlayer::isPlaying()
218{
219 return m_playing;
220}
221
222void NoopAudioPlayer::enqueue(Sound::Type /* sound */)
223{}
224
225void NoopAudioPlayer::pause() 235void NoopAudioPlayer::pause()
226{ 236{
227 m_paused = true; 237 m_paused = true;
@@ -258,7 +268,32 @@ void NoopAudioPlayer::prefinishMarkReached_ex(qint32 mark)
258 emit prefinishMarkReached(mark); 268 emit prefinishMarkReached(mark);
259} 269}
260 270
261void NoopAudioPlayer::test(QFile * /* testsound */, qint32 /* length */) 271void NoopAudioPlayer::seek(qint64 /* time */)
272{}
273
274void NoopAudioPlayer::setWorking(bool working)
275{
276 m_working = working;
277}
278
279void NoopAudioPlayer::test(QFile * /* sound */, unsigned int /* length */)
280{}
281
282void NoopAudioPlayer::play(QFile *sound, unsigned int length)
283{
284 setSource(sound, length);
285 play();
286}
287
288void NoopAudioPlayer::setSource(QFile * /* sound */, unsigned int /* length */)
289{}
290
291bool NoopAudioPlayer::isPlaying()
292{
293 return m_playing;
294}
295
296void NoopAudioPlayer::enqueue(QFile * /* sound */, unsigned int /* length */)
262{} 297{}
263 298
264/* --------------------------------------------------------------- */ 299/* --------------------------------------------------------------- */
@@ -270,13 +305,13 @@ FakeAudioPlayer::FakeAudioPlayer(QObject *parent)
270 connect(&m_timer, SIGNAL(timeout()), this, SLOT(finished_ex())); 305 connect(&m_timer, SIGNAL(timeout()), this, SLOT(finished_ex()));
271} 306}
272 307
273void FakeAudioPlayer::play(Sound::Type sound) 308void FakeAudioPlayer::play(QFile * /* sound */, unsigned int length)
274{ 309{
275 m_playing = true; 310 m_playing = true;
276 m_paused = false; 311 m_paused = false;
277 312
278 m_timer.setSingleShot(true); 313 m_timer.setSingleShot(true);
279 unsigned int interval = Sound::length[sound]; 314 unsigned int interval = length;
280 /* add a small delay server side only */ 315 /* add a small delay server side only */
281 if (Constants::server) 316 if (Constants::server)
282 interval += Constants::tick; 317 interval += Constants::tick;
@@ -299,17 +334,15 @@ GaplessAudioPlayer::GaplessAudioPlayer(Sound::Type sound, qint32 mark, QObject *
299 if (!m_working) 334 if (!m_working)
300 return; 335 return;
301 336
302 m_player1 = AudioManager::self()->createAudioPlayer(); 337 m_player1 = AudioManager::self()->createAudioPlayer(this);
303 m_player2 = AudioManager::self()->createAudioPlayer(); 338 m_player2 = AudioManager::self()->createAudioPlayer(this);
304 339
340 /* this doesn't work reliable on all platforms (e.g. windows) */
305 m_player2->setPrefinishMark(mark); 341 m_player2->setPrefinishMark(mark);
306 m_player1->setPrefinishMark(mark); 342 m_player1->setPrefinishMark(mark);
307 343
308 connect(m_player1, SIGNAL(prefinishMarkReached(qint32)), this, SLOT(startPlayer2())); 344 connect(m_player1, SIGNAL(prefinishMarkReached(qint32)), this, SLOT(startPlayer2()));
309 connect(m_player2, SIGNAL(prefinishMarkReached(qint32)), this, SLOT(startPlayer1())); 345 connect(m_player2, SIGNAL(prefinishMarkReached(qint32)), this, SLOT(startPlayer1()));
310
311 AudioManager::self()->registerAudioPlayer(m_player1);
312 AudioManager::self()->registerAudioPlayer(m_player2);
313} 346}
314 347
315bool GaplessAudioPlayer::isWorking() const 348bool GaplessAudioPlayer::isWorking() const
@@ -350,10 +383,12 @@ void GaplessAudioPlayer::pause()
350 383
351void GaplessAudioPlayer::startPlayer1() 384void GaplessAudioPlayer::startPlayer1()
352{ 385{
353 m_player1->play(m_sound); 386 AudioManager::self()->play(m_sound, m_player1);
387 m_player2->pause();
354} 388}
355 389
356void GaplessAudioPlayer::startPlayer2() 390void GaplessAudioPlayer::startPlayer2()
357{ 391{
358 m_player2->play(m_sound); 392 AudioManager::self()->play(m_sound, m_player2);
393 m_player1->pause();
359} 394}
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 @@
1#ifndef AUDIO_H 1#ifndef AUDIO_H
2#define AUDIO_H 2#define AUDIO_H
3 3
4#include "audiointerface.h"
4#include <QObject> 5#include <QObject>
5#include <QList> 6#include <QList>
6#include <QFile> 7#include <QFile>
@@ -19,52 +20,12 @@ namespace Sound
19 }; 20 };
20 21
21 const unsigned int length[] = { 22 const unsigned int length[] = {
22 4310, 2090, 570, 570, 1720, 23 4310, 2090, 570, 570, 1720, 1990
23 }; 24 };
24}; 25};
25 26
26/* --------------------------------------------------------------- */ 27/* --------------------------------------------------------------- */
27 28
28class AudioPlayer
29 : public QObject
30{
31 Q_OBJECT
32 friend class AudioManager;
33
34public:
35 AudioPlayer(QObject *parent = 0)
36 : QObject(parent)
37 {}
38 virtual ~AudioPlayer()
39 {}
40 virtual bool isWorking() const = 0;
41 virtual void setMuted(bool mute = true) = 0;
42 virtual bool isMuted() const = 0;
43 virtual void play() = 0;
44 virtual void play(Sound::Type sound) = 0;
45 virtual bool isPlaying() = 0;
46 virtual void enqueue(Sound::Type sound) = 0;
47 virtual void pause() = 0;
48 virtual bool isPaused() = 0;
49 virtual void stop() = 0;
50 virtual bool isStopped() = 0;
51 virtual void clear() = 0;
52 virtual void clearQueue() = 0;
53 virtual void setPrefinishMark(qint32 msecToEnd) = 0;
54
55protected slots:
56 virtual void prefinishMarkReached_ex(qint32 mark) = 0;
57
58signals:
59 void finished();
60 void prefinishMarkReached(qint32 mark);
61
62protected:
63 virtual void test(QFile *testsound, qint32 length) = 0;
64};
65
66/* --------------------------------------------------------------- */
67
68class NoopAudioPlayer 29class NoopAudioPlayer
69 : public AudioPlayer 30 : public AudioPlayer
70{ 31{
@@ -72,14 +33,11 @@ class NoopAudioPlayer
72 friend class AudioManager; 33 friend class AudioManager;
73 34
74public: 35public:
75 NoopAudioPlayer(QObject *parent = 0);
76 virtual bool isWorking() const; 36 virtual bool isWorking() const;
77 virtual void setMuted(bool mute = true); 37 virtual void setMuted(bool mute = true);
78 virtual bool isMuted() const; 38 virtual bool isMuted() const;
79 virtual void play(); 39 virtual void play();
80 virtual void play(Sound::Type sound);
81 virtual bool isPlaying(); 40 virtual bool isPlaying();
82 virtual void enqueue(Sound::Type sound);
83 virtual void pause(); 41 virtual void pause();
84 virtual bool isPaused(); 42 virtual bool isPaused();
85 virtual void stop(); 43 virtual void stop();
@@ -87,14 +45,20 @@ public:
87 virtual void clear(); 45 virtual void clear();
88 virtual void clearQueue(); 46 virtual void clearQueue();
89 virtual void setPrefinishMark(qint32 msecToEnd); 47 virtual void setPrefinishMark(qint32 msecToEnd);
48 virtual void seek(qint64 time);
49
50protected:
51 NoopAudioPlayer(QObject *parent = 0);
52 virtual void setWorking(bool working = true);
53 virtual void test(QFile *sound, unsigned int length);
54 virtual void play(QFile *sound, unsigned int length);
55 virtual void setSource(QFile *sound, unsigned int length);
56 virtual void enqueue(QFile *sound, unsigned int length);
90 57
91protected slots: 58protected slots:
92 virtual void prefinishMarkReached_ex(qint32 mark); 59 virtual void prefinishMarkReached_ex(qint32 mark);
93 60
94protected: 61protected:
95 virtual void test(QFile *testsound, qint32 length);
96
97protected:
98 bool m_working; 62 bool m_working;
99 bool m_muted; 63 bool m_muted;
100 bool m_playing; 64 bool m_playing;
@@ -109,9 +73,9 @@ class FakeAudioPlayer
109 Q_OBJECT 73 Q_OBJECT
110 friend class AudioManager; 74 friend class AudioManager;
111 75
112public: 76protected:
113 FakeAudioPlayer(QObject *parent = 0); 77 FakeAudioPlayer(QObject *parent = 0);
114 virtual void play(Sound::Type sound); 78 virtual void play(QFile *sound, unsigned int length);
115 79
116protected slots: 80protected slots:
117 void finished_ex(); 81 void finished_ex();
@@ -148,27 +112,6 @@ protected:
148 112
149/* --------------------------------------------------------------- */ 113/* --------------------------------------------------------------- */
150 114
151class AudioPlayerFactory
152{
153public:
154 virtual ~AudioPlayerFactory()
155 {}
156 virtual AudioPlayer *create(QObject *parent = 0) = 0;
157};
158
159Q_DECLARE_INTERFACE(AudioPlayerFactory, "at.ac.tuwien.foop.pacman.AudioPlayerFactory/1.0");
160
161/* --------------------------------------------------------------- */
162
163class NoopAudioPlayerFactory
164 : public AudioPlayerFactory
165{
166public:
167 virtual AudioPlayer *create(QObject *parent = 0);
168};
169
170/* --------------------------------------------------------------- */
171
172class AudioManager 115class AudioManager
173 : public QObject 116 : public QObject
174{ 117{
@@ -189,8 +132,9 @@ public:
189 AudioPlayer *audioPlayer(); 132 AudioPlayer *audioPlayer();
190 void registerAudioPlayer(AudioPlayer *player); 133 void registerAudioPlayer(AudioPlayer *player);
191 void unregisterAudioPlayer(AudioPlayer *player); 134 void unregisterAudioPlayer(AudioPlayer *player);
192 135 void play(Sound::Type sound, AudioPlayer *player = NULL);
193 QFile *sound(Sound::Type sound); 136 void setSource(Sound::Type sound, AudioPlayer *player = NULL);
137 void enqueue(Sound::Type sound, AudioPlayer *player = NULL);
194 138
195signals: 139signals:
196 void mutedChanged(bool muted); 140 void mutedChanged(bool muted);
@@ -200,8 +144,10 @@ private slots:
200 144
201protected: 145protected:
202 void preload(); 146 void preload();
203 bool tryLoadPhononPlugin(); 147 bool tryLoadAudioPlugin(const QString &libraryname);
204 AudioPlayer *createAudioPlayer(); 148 AudioPlayer *createAudioPlayer(QObject *parent = 0);
149 QFile *sound(Sound::Type sound);
150 unsigned int length(Sound::Type sound);
205 151
206private: 152private:
207 bool m_muted; 153 bool m_muted;
@@ -212,4 +158,4 @@ private:
212 AudioPlayerFactory *m_factory; 158 AudioPlayerFactory *m_factory;
213}; 159};
214 160
215#endif // AUDIOPLAYER_H 161#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 @@
1#ifndef AUDIOINTERFACE_H
2#define AUDIOINTERFACE_H
3
4#include <QObject>
5#include <QFile>
6
7class AudioPlayer
8 : public QObject
9{
10 Q_OBJECT
11 friend class AudioManager;
12
13public:
14 virtual ~AudioPlayer()
15 {}
16 virtual bool isWorking() const = 0;
17 virtual void setMuted(bool mute = true) = 0;
18 virtual bool isMuted() const = 0;
19 virtual void play() = 0;
20 virtual bool isPlaying() = 0;
21 virtual void pause() = 0;
22 virtual bool isPaused() = 0;
23 virtual void stop() = 0;
24 virtual bool isStopped() = 0;
25 virtual void clear() = 0;
26 virtual void clearQueue() = 0;
27 virtual void setPrefinishMark(qint32 msecToEnd) = 0;
28 virtual void seek(qint64 time) = 0;
29
30signals:
31 void finished();
32 void prefinishMarkReached(qint32 mark);
33
34protected:
35 AudioPlayer(QObject *parent = 0)
36 : QObject(parent)
37 {}
38 virtual void setWorking(bool working = true) = 0;
39 virtual void test(QFile *sound, unsigned int length) = 0;
40 virtual void play(QFile *sound, unsigned int length) = 0;
41 virtual void setSource(QFile *sound, unsigned int length) = 0;
42 virtual void enqueue(QFile *sound, unsigned int length) = 0;
43
44protected slots:
45 virtual void prefinishMarkReached_ex(qint32 mark) = 0;
46};
47
48/* --------------------------------------------------------------- */
49
50class AudioPlayerFactory
51{
52public:
53 virtual ~AudioPlayerFactory()
54 {}
55 virtual AudioPlayer *create(QObject *parent = 0) = 0;
56};
57
58Q_DECLARE_INTERFACE(AudioPlayerFactory, "at.ac.tuwien.foop.pacman.AudioPlayerFactory/1.0");
59
60#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 \
24 audio.h \ 24 audio.h \
25 sceneholder.h \ 25 sceneholder.h \
26 util.h \ 26 util.h \
27 gameentity.h 27 gameentity.h \
28 audiointerface.h
28 29
29OTHER_FILES += style.qss \ 30OTHER_FILES += style.qss \
30 pacman.rc 31 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 {
22 const unsigned int port = 7321; 22 const unsigned int port = 7321;
23 const unsigned int connection_timeout = 3000; 23 const unsigned int connection_timeout = 3000;
24 const unsigned int packet_timeout = 3000; 24 const unsigned int packet_timeout = 3000;
25 const unsigned int recv_interval = Constants::tick / 2;
25 } 26 }
26 27
27 namespace Game 28 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)
23void SceneHolder::reset() 23void SceneHolder::reset()
24{ 24{
25 processDelayedItems(); 25 processDelayedItems();
26 showEatingText(false); 26 hideOverlayText();
27 27
28 /* remove actors from scene so they don't get deleted during clear */ 28 /* remove actors from scene so they don't get deleted during clear */
29 foreach(Actor *actor, m_actors) 29 foreach(Actor *actor, m_actors)
@@ -272,15 +272,22 @@ QList<Color::Color> &SceneHolder::eatingOrder()
272 return m_eatingorder; 272 return m_eatingorder;
273} 273}
274 274
275void SceneHolder::showEatingText(bool show) 275void SceneHolder::hideOverlayText()
276{ 276{
277 if (!show) 277 if (m_overlayText->scene() == this)
278 { 278 removeItem(m_overlayText);
279 if (m_overlayText->scene() == this) 279}
280 removeItem(m_overlayText); 280
281 return; 281void SceneHolder::centerOverlayText(unsigned int lines)
282 } 282{
283 QFontMetrics metrics(m_overlayText->font());
284 m_overlayText->setPos((width() - m_overlayText->textWidth()) / 2, (height() - metrics.height() * lines) / 2);
285 m_overlayText->setZValue(100);
286}
283 287
288void SceneHolder::showEatingText()
289{
290 hideOverlayText();
284 m_overlayText->setDefaultTextColor(Qt::black); 291 m_overlayText->setDefaultTextColor(Qt::black);
285 QString text = QString( 292 QString text = QString(
286 "<div style=\"background-color: gray;\" align=\"center\">" 293 "<div style=\"background-color: gray;\" align=\"center\">"
@@ -307,23 +314,14 @@ void SceneHolder::showEatingText(bool show)
307 m_overlayText->setHtml(text); 314 m_overlayText->setHtml(text);
308 m_overlayText->setTextWidth(150); 315 m_overlayText->setTextWidth(150);
309 m_overlayText->setOpacity(0.9); 316 m_overlayText->setOpacity(0.9);
310 317 centerOverlayText(lines);
311 QFontMetrics metrics(m_overlayText->font());
312 m_overlayText->setPos((width() - m_overlayText->textWidth()) / 2, (height() - metrics.height() * lines) / 2);
313 m_overlayText->setZValue(100);
314 318
315 addItem(m_overlayText); 319 addItem(m_overlayText);
316} 320}
317 321
318void SceneHolder::showWaitingForPlayers(bool show) 322void SceneHolder::showWaitingForPlayers()
319{ 323{
320 if (!show) 324 hideOverlayText();
321 {
322 if (m_overlayText->scene() == this)
323 removeItem(m_overlayText);
324 return;
325 }
326
327 m_overlayText->setDefaultTextColor(Qt::black); 325 m_overlayText->setDefaultTextColor(Qt::black);
328 QString text = QString( 326 QString text = QString(
329 "<div style=\"background-color: gray;\" align=\"center\">" 327 "<div style=\"background-color: gray;\" align=\"center\">"
@@ -335,10 +333,26 @@ void SceneHolder::showWaitingForPlayers(bool show)
335 m_overlayText->setHtml(text); 333 m_overlayText->setHtml(text);
336 m_overlayText->setTextWidth(150); 334 m_overlayText->setTextWidth(150);
337 m_overlayText->setOpacity(0.9); 335 m_overlayText->setOpacity(0.9);
336 centerOverlayText(lines);
338 337
339 QFontMetrics metrics(m_overlayText->font()); 338 addItem(m_overlayText);
340 m_overlayText->setPos((width() - m_overlayText->textWidth()) / 2, (height() - metrics.height() * lines) / 2); 339}
341 m_overlayText->setZValue(100); 340
341void SceneHolder::showWonLost(bool won)
342{
343 hideOverlayText();
344 m_overlayText->setDefaultTextColor(Qt::black);
345 QString text = QString(
346 "<div style=\"background-color: gray;\" align=\"center\">"
347 "<br />"
348 "You %1!<br />"
349 "</div>"
350 ).arg((won) ? "won" : "lost");
351 unsigned int lines = 3;
352 m_overlayText->setHtml(text);
353 m_overlayText->setTextWidth(150);
354 m_overlayText->setOpacity(0.9);
355 centerOverlayText(lines);
342 356
343 addItem(m_overlayText); 357 addItem(m_overlayText);
344} 358}
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:
24 Color::Color color(); 24 Color::Color color();
25 void setEatingOrder(QList<Color::Color> &order); 25 void setEatingOrder(QList<Color::Color> &order);
26 QList<Color::Color> &eatingOrder(); 26 QList<Color::Color> &eatingOrder();
27 void showEatingText(bool show = true); 27
28 void showWaitingForPlayers(bool show = true); 28 void hideOverlayText();
29 void centerOverlayText(unsigned int lines);
30 void showEatingText();
31 void showWaitingForPlayers();
32 void showWonLost(bool won);
29 33
30signals: 34signals:
31 void allPointsRemoved(); 35 void allPointsRemoved();
diff --git a/pacman-c++/phononplayer/phononplayer.cpp b/pacman-c++/phononplayer/phononplayer.cpp
index 1f537d6..3d7b446 100644
--- a/pacman-c++/phononplayer/phononplayer.cpp
+++ b/pacman-c++/phononplayer/phononplayer.cpp
@@ -1,4 +1,5 @@
1#include "phononplayer.h" 1#include "phononplayer.h"
2#include "audio.h"
2#include <QtPlugin> 3#include <QtPlugin>
3#include <QCoreApplication> 4#include <QCoreApplication>
4 5
@@ -12,9 +13,8 @@ Q_EXPORT_PLUGIN2(phononplayer, PhononPlayerFactory)
12/* --------------------------------------------------------------- */ 13/* --------------------------------------------------------------- */
13 14
14PhononPlayer::PhononPlayer(QObject *parent) 15PhononPlayer::PhononPlayer(QObject *parent)
15 : AudioPlayer(parent) 16 : AudioPlayer(parent), m_working(false)
16{ 17{
17 m_working = AudioManager::isWorking();
18 m_player = new Phonon::MediaObject(this); 18 m_player = new Phonon::MediaObject(this);
19 m_output = new Phonon::AudioOutput(Phonon::MusicCategory, this); 19 m_output = new Phonon::AudioOutput(Phonon::MusicCategory, this);
20 Phonon::createPath(m_player, m_output); 20 Phonon::createPath(m_player, m_output);
@@ -39,25 +39,36 @@ bool PhononPlayer::isMuted() const
39 39
40void PhononPlayer::play() 40void PhononPlayer::play()
41{ 41{
42 if (!m_working)
43 return;
42 m_player->play(); 44 m_player->play();
43} 45}
44 46
45void PhononPlayer::play(Sound::Type sound) 47void PhononPlayer::play(QFile *sound, unsigned int length)
46{ 48{
47 if (!m_working) 49 if (!m_working)
48 return; 50 return;
49 m_player->setCurrentSource(Phonon::MediaSource(AudioManager::self()->sound(sound))); 51 setSource(sound, length);
50 play(); 52 play();
51} 53}
52 54
55void PhononPlayer::setSource(QFile *sound, unsigned int /* length */)
56{
57 if (!m_working)
58 return;
59 m_player->setCurrentSource(Phonon::MediaSource(sound));
60}
61
53bool PhononPlayer::isPlaying() 62bool PhononPlayer::isPlaying()
54{ 63{
55 return m_player->state() == Phonon::PlayingState; 64 return m_player->state() == Phonon::PlayingState;
56} 65}
57 66
58void PhononPlayer::enqueue(Sound::Type sound) 67void PhononPlayer::enqueue(QFile *sound, unsigned int /* length */)
59{ 68{
60 m_player->enqueue(Phonon::MediaSource(AudioManager::self()->sound(sound))); 69 if (!m_working)
70 return;
71 m_player->enqueue(Phonon::MediaSource(sound));
61} 72}
62 73
63void PhononPlayer::pause() 74void PhononPlayer::pause()
@@ -96,12 +107,22 @@ void PhononPlayer::setPrefinishMark(qint32 msecToEnd)
96 m_player->setPrefinishMark(msecToEnd); 107 m_player->setPrefinishMark(msecToEnd);
97} 108}
98 109
110void PhononPlayer::seek(qint64 time)
111{
112 m_player->seek(time);
113}
114
115void PhononPlayer::setWorking(bool working)
116{
117 m_working = working;
118}
119
99/* this is a simple hack to check if phonon can actually play sounds.. */ 120/* this is a simple hack to check if phonon can actually play sounds.. */
100void PhononPlayer::test(QFile *testsound, qint32 length) 121void PhononPlayer::test(QFile *sound, unsigned int length)
101{ 122{
102 m_player->stop(); 123 m_player->stop();
103 m_output->setVolume(0); 124 m_output->setVolume(0);
104 m_player->setCurrentSource(Phonon::MediaSource(testsound)); 125 m_player->setCurrentSource(Phonon::MediaSource(sound));
105 connect(m_player, SIGNAL(stateChanged(Phonon::State, Phonon::State)), this, SLOT(stateChanged_ex(Phonon::State, Phonon::State))); 126 connect(m_player, SIGNAL(stateChanged(Phonon::State, Phonon::State)), this, SLOT(stateChanged_ex(Phonon::State, Phonon::State)));
106 m_player->play(); 127 m_player->play();
107 128
diff --git a/pacman-c++/phononplayer/phononplayer.h b/pacman-c++/phononplayer/phononplayer.h
index ca56726..8b9ab06 100644
--- a/pacman-c++/phononplayer/phononplayer.h
+++ b/pacman-c++/phononplayer/phononplayer.h
@@ -1,7 +1,7 @@
1#ifndef PHONONPLAYER_H 1#ifndef PHONONPLAYER_H
2#define PHONONPLAYER_H 2#define PHONONPLAYER_H
3 3
4#include "audio.h" 4#include "audiointerface.h"
5#include <QObject> 5#include <QObject>
6#include <QFile> 6#include <QFile>
7#include <QThread> 7#include <QThread>
@@ -25,6 +25,7 @@ class PhononPlayer
25{ 25{
26 Q_OBJECT 26 Q_OBJECT
27 friend class AudioManager; 27 friend class AudioManager;
28 friend class PhononPlayerFactory;
28 29
29private: 30private:
30 class Sleeper 31 class Sleeper
@@ -37,14 +38,11 @@ private:
37 }; 38 };
38 39
39public: 40public:
40 PhononPlayer(QObject *parent = 0);
41 virtual bool isWorking() const; 41 virtual bool isWorking() const;
42 virtual void setMuted(bool mute = true); 42 virtual void setMuted(bool mute = true);
43 virtual bool isMuted() const; 43 virtual bool isMuted() const;
44 virtual void play(); 44 virtual void play();
45 virtual void play(Sound::Type sound);
46 virtual bool isPlaying(); 45 virtual bool isPlaying();
47 virtual void enqueue(Sound::Type sound);
48 virtual void pause(); 46 virtual void pause();
49 virtual bool isPaused(); 47 virtual bool isPaused();
50 virtual void stop(); 48 virtual void stop();
@@ -52,9 +50,15 @@ public:
52 virtual void clear(); 50 virtual void clear();
53 virtual void clearQueue(); 51 virtual void clearQueue();
54 virtual void setPrefinishMark(qint32 msecToEnd); 52 virtual void setPrefinishMark(qint32 msecToEnd);
53 virtual void seek(qint64 time);
55 54
56protected: 55protected:
57 void test(QFile *testsound, qint32 length); 56 PhononPlayer(QObject *parent = 0);
57 virtual void setWorking(bool working = true);
58 void test(QFile *sound, unsigned int length);
59 virtual void play(QFile *sound, unsigned int length);
60 virtual void setSource(QFile *sound, unsigned int length);
61 virtual void enqueue(QFile *sound, unsigned int length);
58 62
59protected slots: 63protected slots:
60 virtual void prefinishMarkReached_ex(qint32 mark); 64 virtual void prefinishMarkReached_ex(qint32 mark);
diff --git a/pacman-c++/phononplayer/phononplayer.pro b/pacman-c++/phononplayer/phononplayer.pro
index 9482454..a11626c 100644
--- a/pacman-c++/phononplayer/phononplayer.pro
+++ b/pacman-c++/phononplayer/phononplayer.pro
@@ -8,4 +8,5 @@ QT += phonon
8include(../common.pri) 8include(../common.pri)
9 9
10SOURCES += phononplayer.cpp 10SOURCES += phononplayer.cpp
11HEADERS += phononplayer.h 11HEADERS += phononplayer.h \
12 ../common/audiointerface.h
diff --git a/pacman-c++/proto/pacman.proto b/pacman-c++/proto/pacman.proto
index 8e088e8..cc4aabc 100644
--- a/pacman-c++/proto/pacman.proto
+++ b/pacman-c++/proto/pacman.proto
@@ -1,7 +1,7 @@
1package ProtoBuf; 1package ProtoBuf;
2 2
3message KeyPressUpdate { 3message ClientUpdate {
4 required uint32 newKey = 1; 4 required uint32 new_direction = 1;
5} 5}
6 6
7message Init { 7message Init {
diff --git a/pacman-c++/server/server.cpp b/pacman-c++/server/server.cpp
index 877c4a6..316b719 100644
--- a/pacman-c++/server/server.cpp
+++ b/pacman-c++/server/server.cpp
@@ -84,8 +84,8 @@ void Server::tick()
84 return; 84 return;
85 } 85 }
86 86
87 /* fetch key updates */ 87 /* fetch client updates */
88 keyPressUpdate(); 88 readClientUpdates();
89 89
90 /* let the bots move */ 90 /* let the bots move */
91 foreach (Color::Color color, m_bots) 91 foreach (Color::Color color, m_bots)
@@ -402,7 +402,7 @@ bool Server::waitForClientConnections()
402 } 402 }
403 403
404 char buf[1024]; 404 char buf[1024];
405 enet_address_get_host_ip(&m_host->address, buf, 1024); 405 enet_address_get_host_ip(&m_host->address, buf, sizeof(buf));
406 std::cout << "[Server] Listening on: " 406 std::cout << "[Server] Listening on: "
407 << qPrintable(QString("%1:%2").arg(buf).arg(m_host->address.port)) << std::endl; 407 << qPrintable(QString("%1:%2").arg(buf).arg(m_host->address.port)) << std::endl;
408 408
@@ -431,14 +431,18 @@ bool Server::waitForClientConnections()
431 m_clientConnections[event.peer] = color; 431 m_clientConnections[event.peer] = color;
432 packet.set_color(color); 432 packet.set_color(color);
433 Util::sendPacket(packet, event.peer, m_host); 433 Util::sendPacket(packet, event.peer, m_host);
434 std::cout << "[Connect] New Player: color=" << qPrintable(Util::colorToString(color)) << std::endl; 434
435 char buf[1024];
436 enet_address_get_host_ip(&event.peer->address, buf, sizeof(buf));
437 std::cout << "[Connect] New Player: color=" << qPrintable(Util::colorToString(color))
438 << ", address=" << buf << ':' << event.peer->address.port << std::endl;
435 } 439 }
436 break; 440 break;
437 case ENET_EVENT_TYPE_RECEIVE: 441 case ENET_EVENT_TYPE_RECEIVE:
438 keyPressUpdate(&event); 442 processClientUpdate(&event);
439 break; 443 break;
440 case ENET_EVENT_TYPE_DISCONNECT: 444 case ENET_EVENT_TYPE_DISCONNECT:
441 keyPressUpdate(&event); 445 processClientUpdate(&event);
442 break; 446 break;
443 default: 447 default:
444 break; 448 break;
@@ -626,28 +630,29 @@ void Server::botCalculate(Actor *actor)
626 m_actorMovements[actor->color()] = list.at(rand); 630 m_actorMovements[actor->color()] = list.at(rand);
627} 631}
628 632
629void Server::keyPressUpdate() 633void Server::readClientUpdates()
630{ 634{
631 ProtoBuf::KeyPressUpdate packet;
632 ENetEvent event; 635 ENetEvent event;
633 while (enet_host_service(m_host, &event, 1) > 0) 636 while (enet_host_service(m_host, &event, 1) > 0)
634 keyPressUpdate(&event); 637 processClientUpdate(&event);
635} 638}
636 639
637void Server::keyPressUpdate(ENetEvent *event) 640void Server::processClientUpdate(ENetEvent *event)
638{ 641{
639 ProtoBuf::KeyPressUpdate packet;
640 switch(event->type) 642 switch(event->type)
641 { 643 {
642 case ENET_EVENT_TYPE_RECEIVE: 644 case ENET_EVENT_TYPE_RECEIVE:
643 { 645 {
644 QSharedPointer<QByteArray> data = Util::receivePacket(event->packet); 646 QSharedPointer<QByteArray> data = Util::receivePacket(event->packet);
645 enet_packet_destroy(event->packet); 647 enet_packet_destroy(event->packet);
646 bool worked = packet.ParseFromArray(data->data(), data->size()); 648 ProtoBuf::ClientUpdate packet;
647 Q_ASSERT(worked);
648 Q_UNUSED(worked);
649 Transmission::field_t direction = packet.newkey();
650 Color::Color color = m_clientConnections[event->peer]; 649 Color::Color color = m_clientConnections[event->peer];
650 if (!packet.ParseFromArray(data->data(), data->size()))
651 {
652 qWarning() << "Invalid packet from client color=" << color;
653 return;
654 }
655 Transmission::field_t direction = packet.new_direction();
651 qDebug() << "[KeyPress] actor=" << color << "direction=" << direction; 656 qDebug() << "[KeyPress] actor=" << color << "direction=" << direction;
652 m_actorMovements[color] = Util::transmissionMovementToActor(direction); 657 m_actorMovements[color] = Util::transmissionMovementToActor(direction);
653 } 658 }
@@ -760,7 +765,7 @@ void Server::initRoundMap()
760 765
761 disconnect(AudioManager::self()->audioPlayer(), NULL, this, NULL); 766 disconnect(AudioManager::self()->audioPlayer(), NULL, this, NULL);
762 connect(AudioManager::self()->audioPlayer(), SIGNAL(finished()), this, SLOT(startGame())); 767 connect(AudioManager::self()->audioPlayer(), SIGNAL(finished()), this, SLOT(startGame()));
763 AudioManager::self()->audioPlayer()->play(Sound::Intro); 768 AudioManager::self()->play(Sound::Intro);
764 m_tickTimer->start(); 769 m_tickTimer->start();
765} 770}
766 771
@@ -782,7 +787,7 @@ void Server::stopGame(bool delay)
782 { 787 {
783 disconnect(AudioManager::self()->audioPlayer(), NULL, this, NULL); 788 disconnect(AudioManager::self()->audioPlayer(), NULL, this, NULL);
784 connect(AudioManager::self()->audioPlayer(), SIGNAL(finished()), this, SLOT(stopGame())); 789 connect(AudioManager::self()->audioPlayer(), SIGNAL(finished()), this, SLOT(stopGame()));
785 AudioManager::self()->audioPlayer()->play(Sound::Die); 790 AudioManager::self()->play(Sound::Die);
786 return; 791 return;
787 } 792 }
788 793
diff --git a/pacman-c++/server/server.h b/pacman-c++/server/server.h
index 857f23d..26c1af2 100644
--- a/pacman-c++/server/server.h
+++ b/pacman-c++/server/server.h
@@ -11,8 +11,6 @@ extern "C" {
11#include "enet/enet.h" 11#include "enet/enet.h"
12} 12}
13 13
14class QTcpSocket;
15
16class Server 14class Server
17 : public SceneHolder 15 : public SceneHolder
18{ 16{
@@ -27,8 +25,8 @@ protected slots:
27 void tick(); 25 void tick();
28 26
29 /* receive updates of client */ 27 /* receive updates of client */
30 void keyPressUpdate(); 28 void readClientUpdates();
31 void keyPressUpdate(ENetEvent *event); 29 void processClientUpdate(ENetEvent *event);
32 30
33protected: 31protected:
34 /* block until we have connections from all clients */ 32 /* block until we have connections from all clients */