From 573e2dd6b6c5f4a9895af947a264aee39a1f3620 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20Gro=C3=9F?= Date: Tue, 28 Feb 2012 13:14:02 +0100 Subject: [PATCH] [qcross] added saving/loading game support --- qcross/cgamewindow.cpp | 140 +++++++++++++++++++++++++++++------------ qcross/cgamewindow.h | 7 ++- 2 files changed, 106 insertions(+), 41 deletions(-) diff --git a/qcross/cgamewindow.cpp b/qcross/cgamewindow.cpp index 348950d..dd08de8 100644 --- a/qcross/cgamewindow.cpp +++ b/qcross/cgamewindow.cpp @@ -77,16 +77,18 @@ namespace qcross { currentMenu = menuBar()->addMenu(tr("&Game")); currentMenu->addAction(tr("&New..."), this, SLOT(newGame()), Qt::CTRL + Qt::Key_N); currentMenu->addSeparator(); - currentMenu->addAction(tr("&Save..."), this, SLOT(saveGame()), Qt::CTRL + Qt::Key_N); + m_SaveGameAction = currentMenu->addAction(tr("&Save..."), this, SLOT(saveGame()), Qt::CTRL + Qt::Key_N); + m_SaveGameAction->setEnabled(false); currentMenu->addAction(tr("&Load..."), this, SLOT(loadGame()), Qt::CTRL + Qt::Key_N); currentMenu->addSeparator(); m_RestartGameAction = currentMenu->addAction(tr("&Restart"), this, SLOT(restartGame()), Qt::CTRL + Qt::Key_R); m_RestartGameAction->setEnabled(false); m_PauseGameAction = currentMenu->addAction(tr("&Pause")); - connect(m_PauseGameAction, SIGNAL(toggled(bool)), this, SLOT(pauseGame(bool))); - m_PauseGameAction->setShortcut(Qt::CTRL + Qt::Key_P); - m_PauseGameAction->setCheckable(true); m_PauseGameAction->setEnabled(false); + m_PauseGameAction->setCheckable(true); + m_PauseGameAction->setChecked(true); + m_PauseGameAction->setShortcut(Qt::CTRL + Qt::Key_P); + connect(m_PauseGameAction, SIGNAL(toggled(bool)), this, SLOT(pauseGame(bool))); currentMenu->addSeparator(); currentMenu->addAction(tr("&Quit"), this, SLOT(close()), Qt::CTRL + Qt::Key_Q); currentMenu->addSeparator(); @@ -101,6 +103,76 @@ namespace qcross { currentMenu->addAction(tr("About &Qt"), qApp, SLOT(aboutQt())); } + const char magicSaveGameHeader[] = {'C', 'R', 'S', 'V'}; + + bool CGameWindow::readSaveGame(QDataStream & stream) { + QString stringBuffer; + qint32 intBuffer; + QSize sizeBuffer; + + // picture index + stream >> intBuffer; qDebug("picture index = %i", m_PictureIndex); + if (stream.atEnd()) { + qCritical("invalid savegame"); + return false; + } + m_PictureIndex = intBuffer; + + // package name + if (m_PictureIndex > -1) { + stream >> stringBuffer; qDebug("package name = %s", qPrintable(stringBuffer)); + if (stream.atEnd()) { + qCritical("invalid savegame"); + return false; + } + m_PackageName = stringBuffer; + + stream >> stringBuffer; qDebug("highscoreFileName = %s", qPrintable(stringBuffer)); + if (stream.atEnd()) { + qCritical("invalid savegame"); + return false; + } + + if (m_Highscore) + delete m_Highscore; + + m_Highscore = new CHighscore(0); + m_Highscore->setFileName(QCROSS_STRING_DATAPATH + QDir::separator() + stringBuffer); + m_Highscore->open(); + } + + // picture + if (m_Picture) + delete m_Picture; + + m_Picture = new CNonogram(); + + if (!m_Picture->readFromStream(stream)) { + qCritical("invalid savegame"); + return false; + } + + // TODO handle save game porting properly + // TODO check for matching nonogram + + m_Field->setPicture(m_Picture); + m_Field->applyState(stream); + + return true; + } + + void CGameWindow::writeSaveGame(QDataStream & stream) { + // picture index + stream << qint32(m_PictureIndex); + if (m_PictureIndex > -1) { + stream << m_PackageName; + stream << m_Highscore->fileName().section(QDir::separator(), -1); + } + + m_Picture->writeToStream(stream); + m_Field->dumpState(stream); + } + void CGameWindow::newGame() { bool notPaused = !m_Field->isPaused(); if (notPaused) @@ -112,6 +184,7 @@ namespace qcross { delete m_Highscore; m_Highscore = dialog.takeHighscore(); + m_PackageName = dialog.selectedPackage()->name(); m_PictureIndex = m_Highscore ? dialog.nonogramIndex() : -1; CNonogram * newPicture = dialog.takeNonogram(); @@ -134,9 +207,11 @@ namespace qcross { pauseGame(false); } - const char magicSaveGameHeader[] = {'C', 'R', 'S', 'V'}; void CGameWindow::saveGame() { + if (!m_Picture) + return; + if (!m_Field->isPaused()) m_PauseGameAction->setChecked(true); @@ -151,13 +226,10 @@ namespace qcross { QDataStream out(&file); out.setVersion(QDataStream::Qt_4_0); - out.writeRawData(magicSaveGameHeader, 4); - - out << int(-1); // debug: m_PicutreIndex - - out << *m_Picture; - - m_Field->dumpState(out); + if (out.writeRawData(magicSaveGameHeader, 4) == -1) + qDebug("could not write magic save game header"); + else + writeSaveGame(out); m_PauseGameAction->setChecked(false); } @@ -180,42 +252,30 @@ namespace qcross { char magicHeader[4]; in.readRawData(magicHeader, 4); - qDebug("checking magic header"); + qDebug("checking magic savegame header"); for (int i = 0; i < 4; i++) { if (magicHeader[i] != magicSaveGameHeader[i]) return; } - // picture index - in >> m_PictureIndex; qDebug("m_PictureIndex = %i", m_PictureIndex); - - // delete current highscore - if (m_Highscore) - delete m_Highscore; - - // package name - if (m_PictureIndex > -1) { - QString highscoreFileName, packageName; - in >> packageName; qDebug("packageName = %s", qPrintable(packageName)); - in >> highscoreFileName; qDebug("highscoreFileName = %s", qPrintable(highscoreFileName)); + if (readSaveGame(in)) { + m_PauseGameAction->setEnabled(true); + } + else { + m_Field->setPicture(NULL); + m_PictureIndex = -1; - // TODO handle save game porting correctly - m_Highscore = new CHighscore(0); - m_Highscore->setFileName(QCROSS_STRING_DATAPATH + QDir::separator() + highscoreFileName); - m_Highscore->open(); + if (m_Picture) { + delete m_Picture; + m_Picture = NULL; + } + + if (m_Highscore) { + delete m_Highscore; + m_Highscore = NULL; + } } - // picture - CNonogram * newPicture = new CNonogram(in); - - m_Field->setPicture(newPicture); - if (m_Picture) - delete m_Picture; - - m_Picture = newPicture; - m_Field->applyState(in); - - m_PauseGameAction->setEnabled(true); m_PauseGameAction->setChecked(false); } diff --git a/qcross/cgamewindow.h b/qcross/cgamewindow.h index fbaf767..ac0c1c1 100644 --- a/qcross/cgamewindow.h +++ b/qcross/cgamewindow.h @@ -46,14 +46,19 @@ namespace qcross { CCrossFieldWidget * m_Field; libqnono::CNonogram * m_Picture; - CHighscore * m_Highscore; + QString m_PackageName; int m_PictureIndex; + CHighscore * m_Highscore; + QAction * m_SaveGameAction; QAction * m_RestartGameAction; QAction * m_PauseGameAction; void createActions(); + bool readSaveGame(QDataStream & stream); + void writeSaveGame(QDataStream & stream); + protected slots: void newGame();