From 1bc05562ccc3f9f5ef609cffcf3ef59857dfa34c Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 5 Jun 2011 19:45:37 +0200 Subject: [PATCH] Mulligan crash fix, multi-column screen alignment for multiplayer, Server Win32 compile fix --- cockatrice/src/gamescene.cpp | 116 +++++++++++++++++----------- cockatrice/src/gamescene.h | 3 +- cockatrice/src/messagelogwidget.cpp | 6 +- cockatrice/src/player.cpp | 8 +- cockatrice/src/player.h | 2 +- servatrice/src/main.cpp | 2 + servatrice/src/server_logger.cpp | 11 ++- servatrice/src/server_logger.h | 2 + 8 files changed, 93 insertions(+), 57 deletions(-) diff --git a/cockatrice/src/gamescene.cpp b/cockatrice/src/gamescene.cpp index 7b62db5d..8785adcc 100644 --- a/cockatrice/src/gamescene.cpp +++ b/cockatrice/src/gamescene.cpp @@ -3,6 +3,7 @@ #include "zoneviewwidget.h" #include "zoneviewzone.h" #include "phasestoolbar.h" +#include #include #include #include @@ -31,7 +32,6 @@ void GameScene::addPlayer(Player *player) qDebug("GameScene::addPlayer"); players << player; addItem(player); - rearrange(); connect(player, SIGNAL(sizeChanged()), this, SLOT(rearrange())); connect(player, SIGNAL(gameConceded()), this, SLOT(rearrange())); } @@ -46,44 +46,63 @@ void GameScene::removePlayer(Player *player) void GameScene::rearrange() { - struct PlayerProcessor { - static void processPlayer(Player *p, qreal &w, QPointF &b, bool singlePlayer) - { - if (p->getConceded()) - return; - - const QRectF br = p->boundingRect(); - if (br.width() > w) - w = br.width(); - p->setPos(b); - p->setMirrored((b.y() < playerAreaSpacing) && !singlePlayer); - b += QPointF(0, br.height() + playerAreaSpacing); - } - }; - - qreal sceneHeight = -playerAreaSpacing; + playersByColumn.clear(); + + QList playersPlaying; + int firstPlayer = -1; for (int i = 0; i < players.size(); ++i) - if (!players[i]->getConceded()) - sceneHeight += players[i]->boundingRect().height() + playerAreaSpacing; + if (!players[i]->getConceded()) { + playersPlaying.append(players[i]); + if ((firstPlayer == -1) && (players[i]->getLocal())) + firstPlayer = playersPlaying.size() - 1; + } + if (firstPlayer == -1) + firstPlayer = 0; + const int playersCount = playersPlaying.size(); + const int columns = playersCount < 4 ? 1 : 2; + const int rows = ceil((qreal) playersCount / columns); + + qreal sceneHeight = 0, sceneWidth = -playerAreaSpacing; + QList columnWidth; + int firstPlayerOfColumn = firstPlayer; + for (int col = 0; col < columns; ++col) { + playersByColumn.append(QList()); + columnWidth.append(0); + qreal thisColumnHeight = -playerAreaSpacing; + const int rowsInColumn = rows - (playersCount % columns); + for (int j = 0; j < rowsInColumn; ++j) { + Player *player = playersPlaying[(firstPlayerOfColumn + j) % playersCount]; + if (col == 0) + playersByColumn[col].prepend(player); + else + playersByColumn[col].append(player); + thisColumnHeight += player->boundingRect().height() + playerAreaSpacing; + if (player->boundingRect().width() > columnWidth[col]) + columnWidth[col] = player->boundingRect().width(); + } + if (thisColumnHeight > sceneHeight) + sceneHeight = thisColumnHeight; + sceneWidth += columnWidth[col] + playerAreaSpacing; + + firstPlayerOfColumn += rowsInColumn; + } + phasesToolbar->setHeight(sceneHeight); qreal phasesWidth = phasesToolbar->getWidth(); - - QPointF base(phasesWidth, 0); - qreal sceneWidth; - QList localPlayers; - - for (int i = 0; i < players.size(); ++i) - if (!players[i]->getLocal()) - PlayerProcessor::processPlayer(players[i], sceneWidth, base, players.size() == 1); - else - localPlayers.append(players[i]); - - for (int i = 0; i < localPlayers.size(); ++i) - PlayerProcessor::processPlayer(localPlayers[i], sceneWidth, base, players.size() == 1); - sceneWidth += phasesWidth; - playersRect = QRectF(0, 0, sceneWidth, sceneHeight); - + + qreal x = phasesWidth; + for (int col = 0; col < columns; ++col) { + qreal y = 0; + for (int row = 0; row < playersByColumn[col].size(); ++row) { + Player *player = playersByColumn[col][row]; + player->setPos(x, y); + player->setMirrored(row != rows - 1); + y += player->boundingRect().height() + playerAreaSpacing; + } + x += columnWidth[col] + playerAreaSpacing; + } + setSceneRect(sceneRect().x(), sceneRect().y(), sceneWidth, sceneHeight); processViewSizeChange(viewSize); } @@ -139,24 +158,33 @@ void GameScene::processViewSizeChange(const QSize &newSize) qreal newRatio = ((qreal) newSize.width()) / newSize.height(); qreal minWidth = 0; - for (int i = 0; i < players.size(); ++i) { - qreal w = players[i]->getMinimumWidth(); - if (w > minWidth) - minWidth = w; + QList minWidthByColumn; + for (int col = 0; col < playersByColumn.size(); ++col) { + minWidthByColumn.append(0); + for (int row = 0; row < playersByColumn[col].size(); ++row) { + qreal w = playersByColumn[col][row]->getMinimumWidth(); + if (w > minWidthByColumn[col]) + minWidthByColumn[col] = w; + } + minWidth += minWidthByColumn[col]; } minWidth += phasesToolbar->getWidth(); qreal minRatio = minWidth / sceneRect().height(); + qreal newWidth; if (minRatio > newRatio) { // Aspect ratio is dominated by table width. - setSceneRect(0, 0, minWidth, sceneRect().height()); + newWidth = minWidth; } else { // Aspect ratio is dominated by window dimensions. - setSceneRect(0, 0, newRatio * sceneRect().height(), sceneRect().height()); + newWidth = newRatio * sceneRect().height(); } - - for (int i = 0; i < players.size(); ++i) - players[i]->processSceneSizeChange(sceneRect().size() - QSizeF(phasesToolbar->getWidth(), 0)); + setSceneRect(0, 0, newWidth, sceneRect().height()); + + qreal extraWidthPerColumn = (newWidth - minWidth) / playersByColumn.size(); + for (int col = 0; col < playersByColumn.size(); ++col) + for (int row = 0; row < playersByColumn[col].size(); ++row) + playersByColumn[col][row]->processSceneSizeChange(minWidthByColumn[col] + extraWidthPerColumn); } void GameScene::updateHover(const QPointF &scenePos) diff --git a/cockatrice/src/gamescene.h b/cockatrice/src/gamescene.h index eee167be..7b93a35f 100644 --- a/cockatrice/src/gamescene.h +++ b/cockatrice/src/gamescene.h @@ -22,7 +22,7 @@ private: PhasesToolbar *phasesToolbar; QList players; - QRectF playersRect; + QList > playersByColumn; QList views; QSize viewSize; QPointer hoveredCard; @@ -33,7 +33,6 @@ public: GameScene(PhasesToolbar *_phasesToolbar, QObject *parent = 0); ~GameScene(); void retranslateUi(); - const QRectF &getPlayersRect() const { return playersRect; } void processViewSizeChange(const QSize &newSize); void startRubberBand(const QPointF &selectionOrigin); diff --git a/cockatrice/src/messagelogwidget.cpp b/cockatrice/src/messagelogwidget.cpp index deafc175..18cf52b8 100644 --- a/cockatrice/src/messagelogwidget.cpp +++ b/cockatrice/src/messagelogwidget.cpp @@ -4,7 +4,6 @@ #include "cardinfowidget.h" #include "protocol_items.h" #include "soundengine.h" -#include #include #include @@ -264,6 +263,9 @@ void MessageLogWidget::logMoveCard(Player *player, CardItem *card, CardZone *sta void MessageLogWidget::logMulligan(Player *player, int number) { + if (!player) + return; + if (number > -1) append(tr("%1 takes a mulligan to %n.", "", number).arg(sanitizeHtml(player->getName()))); else @@ -468,6 +470,7 @@ void MessageLogWidget::containerProcessingStarted(GameEventContext *_context) currentContext = MessageContext_MoveCard; else if (qobject_cast(_context)) { currentContext = MessageContext_Mulligan; + mulliganPlayer = 0; mulliganNumber = static_cast(_context)->getNumber(); } } @@ -482,6 +485,7 @@ void MessageLogWidget::containerProcessingDone() moveCardTapped.clear(); } else if (currentContext == MessageContext_Mulligan) { logMulligan(mulliganPlayer, mulliganNumber); + mulliganPlayer = 0; mulliganNumber = 0; } diff --git a/cockatrice/src/player.cpp b/cockatrice/src/player.cpp index 1b8ec25b..d6a34978 100644 --- a/cockatrice/src/player.cpp +++ b/cockatrice/src/player.cpp @@ -1007,7 +1007,6 @@ void Player::eventDrawCards(Event_DrawCards *event) hand->reorganizeCards(); deck->reorganizeCards(); - emit logDrawCards(this, event->getNumberCards()); } @@ -1545,12 +1544,9 @@ void Player::setMirrored(bool _mirrored) } } -void Player::processSceneSizeChange(const QSizeF &newSize) +void Player::processSceneSizeChange(int newPlayerWidth) { - // This will need to be changed if player areas are displayed side by side (e.g. 2x2 for a 4-player game) - qreal fullPlayerWidth = newSize.width(); - - qreal tableWidth = fullPlayerWidth - CARD_HEIGHT - 15 - counterAreaWidth - stack->boundingRect().width(); + qreal tableWidth = newPlayerWidth - CARD_HEIGHT - 15 - counterAreaWidth - stack->boundingRect().width(); if (!settingsCache->getHorizontalHand()) tableWidth -= hand->boundingRect().width(); diff --git a/cockatrice/src/player.h b/cockatrice/src/player.h index c30fc376..4096c1e9 100644 --- a/cockatrice/src/player.h +++ b/cockatrice/src/player.h @@ -245,7 +245,7 @@ public: qreal getMinimumWidth() const; void setMirrored(bool _mirrored); - void processSceneSizeChange(const QSizeF &newSize); + void processSceneSizeChange(int newPlayerWidth); void processPlayerInfo(ServerInfo_Player *info); void processCardAttachment(ServerInfo_Player *info); diff --git a/servatrice/src/main.cpp b/servatrice/src/main.cpp index a5ebe207..a36e3332 100644 --- a/servatrice/src/main.cpp +++ b/servatrice/src/main.cpp @@ -73,6 +73,7 @@ void myMessageOutput(QtMsgType /*type*/, const char *msg) logger->logMessage(msg); } +#ifdef Q_OS_UNIX void sigSegvHandler(int sig) { if (sig == SIGSEGV) @@ -82,6 +83,7 @@ void sigSegvHandler(int sig) delete loggerThread; raise(sig); } +#endif int main(int argc, char *argv[]) { diff --git a/servatrice/src/server_logger.cpp b/servatrice/src/server_logger.cpp index 0b59c46a..de08c288 100644 --- a/servatrice/src/server_logger.cpp +++ b/servatrice/src/server_logger.cpp @@ -3,8 +3,10 @@ #include #include #include -#include -#include +#ifdef Q_OS_UNIX +# include +# include +#endif ServerLogger::ServerLogger(const QString &logFileName, QObject *parent) : QObject(parent), flushRunning(false) @@ -14,9 +16,10 @@ ServerLogger::ServerLogger(const QString &logFileName, QObject *parent) logFile->open(QIODevice::Append); #ifdef Q_OS_UNIX ::socketpair(AF_UNIX, SOCK_STREAM, 0, sigHupFD); -#endif + snHup = new QSocketNotifier(sigHupFD[1], QSocketNotifier::Read, this); connect(snHup, SIGNAL(activated(int)), this, SLOT(handleSigHup())); +#endif } else logFile = 0; @@ -62,6 +65,7 @@ void ServerLogger::flushBuffer() } } +#ifdef Q_OS_UNIX void ServerLogger::hupSignalHandler(int /*unused*/) { if (!logFile) @@ -85,6 +89,7 @@ void ServerLogger::handleSigHup() snHup->setEnabled(true); } +#endif QFile *ServerLogger::logFile; int ServerLogger::sigHupFD[2]; diff --git a/servatrice/src/server_logger.h b/servatrice/src/server_logger.h index 3d3d4683..62d78537 100644 --- a/servatrice/src/server_logger.h +++ b/servatrice/src/server_logger.h @@ -19,7 +19,9 @@ public: public slots: void logMessage(QString message); private slots: +#ifdef Q_OS_UNIX void handleSigHup(); +#endif void flushBuffer(); signals: void sigFlushBuffer();