# HG changeset patch # User koda # Date 1354582334 -3600 # Node ID 555a6e06cb3309f8a84fbdd5b1e766780257504c # Parent 780e156f19ea013a60e7cd2bd03c6d6d4867713b# Parent f781204831ab4331c9ab8aaf010b66f1ef9cadea second merge diff -r f781204831ab -r 555a6e06cb33 QTfrontend/CMakeLists.txt --- a/QTfrontend/CMakeLists.txt Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/CMakeLists.txt Tue Dec 04 01:52:14 2012 +0100 @@ -20,6 +20,9 @@ find_package(SDL_net REQUIRED) #network frontlib if(NOT NOVIDEOREC) find_package(FFMPEG) + if(${FFMPEG_FOUND}) + add_definitions(-DVIDEOREC -D__STDC_CONSTANT_MACROS) + endif() endif() include_directories(.) @@ -66,10 +69,6 @@ file(GLOB_RECURSE UIcpp ui/*.cpp) file(GLOB UtilCpp util/*.cpp) -if(${FFMPEG_FOUND}) - add_definitions(-DVIDEOREC -D__STDC_CONSTANT_MACROS) -endif() - set(hwfr_src ${ModelCpp} ${NetCpp} diff -r f781204831ab -r 555a6e06cb33 QTfrontend/gameuiconfig.cpp --- a/QTfrontend/gameuiconfig.cpp Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/gameuiconfig.cpp Tue Dec 04 01:52:14 2012 +0100 @@ -94,11 +94,13 @@ Form->ui.pageOptions->editNetPassword->installEventFilter(this); int passLength = value("net/passwordlength", 0).toInt(); - setNetPasswordLength(passLength); - if (savePwd == false) { - Form->ui.pageOptions->editNetPassword->setEnabled(savePwd); + if (!savePwd) { + Form->ui.pageOptions->editNetPassword->setEnabled(false); Form->ui.pageOptions->editNetPassword->setText(""); setNetPasswordLength(0); + } else + { + setNetPasswordLength(passLength); } delete netHost; @@ -139,26 +141,34 @@ void GameUIConfig::reloadVideosValues(void) { - Form->ui.pageVideos->framerateBox->setValue(value("videorec/fps",25).toUInt()); - Form->ui.pageVideos->bitrateBox->setValue(value("videorec/bitrate",400).toUInt()); - bool useGameRes = value("videorec/usegameres",true).toBool(); + // one pass with default values + Form->ui.pageOptions->setDefaultOptions(); + + // then load user configuration + Form->ui.pageOptions->framerateBox->setCurrentIndex( + Form->ui.pageOptions->framerateBox->findData( + value("videorec/framerate", rec_Framerate()).toString() + " fps", + Qt::MatchExactly) ); + Form->ui.pageOptions->bitrateBox->setValue(value("videorec/bitrate", rec_Bitrate()).toUInt()); + bool useGameRes = value("videorec/usegameres",Form->ui.pageOptions->checkUseGameRes->isChecked()).toBool(); if (useGameRes) { QRect res = vid_Resolution(); - Form->ui.pageVideos->widthEdit->setText(QString::number(res.width())); - Form->ui.pageVideos->heightEdit->setText(QString::number(res.height())); + Form->ui.pageOptions->widthEdit->setText(QString::number(res.width())); + Form->ui.pageOptions->heightEdit->setText(QString::number(res.height())); } else { - Form->ui.pageVideos->widthEdit->setText(value("videorec/width","800").toString()); - Form->ui.pageVideos->heightEdit->setText(value("videorec/height","600").toString()); + Form->ui.pageOptions->widthEdit->setText(value("videorec/width","800").toString()); + Form->ui.pageOptions->heightEdit->setText(value("videorec/height","600").toString()); } - Form->ui.pageVideos->checkUseGameRes->setChecked(useGameRes); - Form->ui.pageVideos->checkRecordAudio->setChecked(value("videorec/audio",true).toBool()); - if (!Form->ui.pageVideos->tryCodecs(value("videorec/format","no").toString(), + Form->ui.pageOptions->checkUseGameRes->setChecked(useGameRes); + Form->ui.pageOptions->checkRecordAudio->setChecked( + value("videorec/audio",Form->ui.pageOptions->checkRecordAudio->isChecked()).toBool() ); + if (!Form->ui.pageOptions->tryCodecs(value("videorec/format","no").toString(), value("videorec/videocodec","no").toString(), value("videorec/audiocodec","no").toString())) - Form->ui.pageVideos->setDefaultCodecs(); + Form->ui.pageOptions->setDefaultCodecs(); } QStringList GameUIConfig::GetTeamsList() @@ -177,7 +187,16 @@ void GameUIConfig::resizeToConfigValues() { - Form->resize(value("frontend/width", 800).toUInt(), value("frontend/height", 600).toUInt()); + // fill 2/3 of the screen desktop + const QRect deskSize = QApplication::desktop()->screenGeometry(-1); + Form->resize(value("frontend/width", deskSize.width()*2/3).toUInt(), + value("frontend/height", deskSize.height()*2/3).toUInt()); + + // move the window to the center of the screen + QPoint center = QApplication::desktop()->availableGeometry(-1).center(); + center.setX(center.x() - (Form->width()/2)); + center.setY(center.y() - (Form->height()/2)); + Form->move(center); } void GameUIConfig::SaveOptions() @@ -270,7 +289,7 @@ setValue(QString("colors/color%1").arg(i), model->item(i)->data()); } - Form->gameSettings->sync(); + sync(); } void GameUIConfig::SaveVideosOptions() @@ -279,14 +298,19 @@ setValue("videorec/format", AVFormat()); setValue("videorec/videocodec", videoCodec()); setValue("videorec/audiocodec", audioCodec()); - setValue("videorec/fps", rec_Framerate()); + setValue("videorec/framerate", rec_Framerate()); setValue("videorec/bitrate", rec_Bitrate()); setValue("videorec/width", res.width()); setValue("videorec/height", res.height()); - setValue("videorec/usegameres", Form->ui.pageVideos->checkUseGameRes->isChecked()); + setValue("videorec/usegameres", Form->ui.pageOptions->checkUseGameRes->isChecked()); setValue("videorec/audio", recordAudio()); - Form->gameSettings->sync(); + sync(); +} + +void GameUIConfig::setValue(const QString &key, const QVariant &value) +{ + QSettings::setValue(key, value); } QString GameUIConfig::language() @@ -447,7 +471,7 @@ bool GameUIConfig::netPasswordIsValid() { - return (netPasswordLength() == 0 || Form->ui.pageOptions->editNetPassword->text() != QString(netPasswordLength(), '\0')); + return (netPasswordLength() == 0 || Form->ui.pageOptions->editNetPassword->text() != QString(netPasswordLength(), '*')); } // When hedgewars launches, the password field is set with null characters. If the user tries to edit the field and there are such characters, then clear the field @@ -472,7 +496,7 @@ { if (passwordLength > 0) { - Form->ui.pageOptions->editNetPassword->setText(QString(passwordLength, '\0')); + Form->ui.pageOptions->editNetPassword->setText(QString(passwordLength, '*')); } else { @@ -487,40 +511,43 @@ QString GameUIConfig::AVFormat() { - return Form->ui.pageVideos->format(); + return Form->ui.pageOptions->format(); } QString GameUIConfig::videoCodec() { - return Form->ui.pageVideos->videoCodec(); + return Form->ui.pageOptions->videoCodec(); } QString GameUIConfig::audioCodec() { - return Form->ui.pageVideos->audioCodec(); + return Form->ui.pageOptions->audioCodec(); } QRect GameUIConfig::rec_Resolution() { - if (Form->ui.pageVideos->checkUseGameRes->isChecked()) + if (Form->ui.pageOptions->checkUseGameRes->isChecked()) return vid_Resolution(); QRect res(0,0,0,0); - res.setWidth(Form->ui.pageVideos->widthEdit->text().toUInt()); - res.setHeight(Form->ui.pageVideos->heightEdit->text().toUInt()); + res.setWidth(Form->ui.pageOptions->widthEdit->text().toUInt()); + res.setHeight(Form->ui.pageOptions->heightEdit->text().toUInt()); return res; } int GameUIConfig::rec_Framerate() { - return Form->ui.pageVideos->framerateBox->value(); + // remove the "fps" label + QString fpsText = Form->ui.pageOptions->framerateBox->currentText(); + QStringList fpsList = fpsText.split(" "); + return fpsList.first().toInt(); } int GameUIConfig::rec_Bitrate() { - return Form->ui.pageVideos->bitrateBox->value(); + return Form->ui.pageOptions->bitrateBox->value(); } bool GameUIConfig::recordAudio() { - return Form->ui.pageVideos->checkRecordAudio->isChecked(); + return Form->ui.pageOptions->checkRecordAudio->isChecked(); } diff -r f781204831ab -r 555a6e06cb33 QTfrontend/gameuiconfig.h --- a/QTfrontend/gameuiconfig.h Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/gameuiconfig.h Tue Dec 04 01:52:14 2012 +0100 @@ -58,6 +58,7 @@ bool isFrontendFullscreen() const; void resizeToConfigValues(); quint32 stereoMode() const; + void setValue(const QString & key, const QVariant & value); QString AVFormat(); QString videoCodec(); diff -r f781204831ab -r 555a6e06cb33 QTfrontend/hwform.cpp --- a/QTfrontend/hwform.cpp Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/hwform.cpp Tue Dec 04 01:52:14 2012 +0100 @@ -111,7 +111,6 @@ QString playerHash; GameUIConfig* HWForm::config = NULL; -QSettings* HWForm::gameSettings = NULL; HWForm::HWForm(QWidget *parent, QString styleSheet) : QMainWindow(parent) @@ -127,10 +126,6 @@ #ifdef USE_XFIRE xfire_init(); #endif - gameSettings = new QSettings("physfs://hedgewars.ini", QSettings::IniFormat); - frontendEffects = gameSettings->value("frontend/effects", true).toBool(); - playerHash = QString(QCryptographicHash::hash(gameSettings->value("net/nick","").toString().toUtf8(), QCryptographicHash::Md5).toHex()); - this->setStyleSheet(styleSheet); ui.setupUi(this); setMinimumSize(760, 580); @@ -140,8 +135,16 @@ ui.pageOptions->CBResolution->addItems(SDLInteraction::instance().getResolutions()); config = new GameUIConfig(this, "physfs://hedgewars.ini"); + frontendEffects = config->value("frontend/effects", true).toBool(); + playerHash = QString(QCryptographicHash::hash(config->value("net/nick","").toString().toUtf8(), QCryptographicHash::Md5).toHex()); + ui.pageRoomsList->setSettings(config); + ui.pageNetGame->chatWidget->setSettings(config); + ui.pageRoomsList->chatWidget->setSettings(config); +#ifdef VIDEOREC ui.pageVideos->init(config); + ui.pageOptions->setConfig(config); +#endif #ifdef __APPLE__ panel = new M3Panel; @@ -445,7 +448,7 @@ if(teamslist.empty()) { - QString currentNickName = gameSettings->value("net/nick","").toString().toUtf8(); + QString currentNickName = config->value("net/nick","").toString().toUtf8(); QString teamName; if (currentNickName.isEmpty()) @@ -535,6 +538,69 @@ #ifdef USE_XFIRE updateXfire(); #endif + + QString openPrefix = "Debug: (PAGE_OPENED: "; + QString openSuffix = ")"; + QString closePrefix = "Debug: (PAGE_LEFT: "; + QString closeSuffix = ")"; + + switch (lastid) { //Print the id of the page we're leaving + case ID_PAGE_SETUP_TEAM : qDebug("%sPAGE_SETUP_TEAM%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_SETUP : qDebug("%sPAGE_SETUP%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_MULTIPLAYER : qDebug("%sPAGE_MULTIPLAYER%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_DEMOS : qDebug("%sPAGE_DEMOS%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_NET : qDebug("%sPAGE_NET%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_NETGAME : qDebug("%sPAGE_NETGAME%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_INFO : qDebug("%sPAGE_INFO%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_MAIN : qDebug("%sPAGE_MAIN%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_GAMESTATS : qDebug("%sPAGE_GAMESTATS%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_SINGLEPLAYER : qDebug("%sPAGE_SINGLEPLAYER%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_TRAINING : qDebug("%sPAGE_TRAINING%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_SELECTWEAPON : qDebug("%sPAGE_SELECTWEAPON%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_NETSERVER : qDebug("%sPAGE_NETSERVER%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_INGAME : qDebug("%sPAGE_INGAME%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_ROOMSLIST : qDebug("%sPAGE_ROOMSLIST%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_CONNECTING : qDebug("%sPAGE_CONNECTING%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_SCHEME : qDebug("%sPAGE_SCHEME%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_ADMIN : qDebug("%sPAGE_ADMIN%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_NETTYPE : qDebug("%sPAGE_NETTYPE%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_CAMPAIGN : qDebug("%sPAGE_CAMPAIGN%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_DRAWMAP : qDebug("%sPAGE_DRAWMAP%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_DATADOWNLOAD : qDebug("%sPAGE_DATADOWNLOAD%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_FEEDBACK : qDebug("%sPAGE_FEEDBACK%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case ID_PAGE_VIDEOS : qDebug("%sPAGE_VIDEOS%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + case MAX_PAGE : qDebug("%sMAX_PAGE%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + default : qDebug("%sUNKNOWN PAGE%s", qPrintable(closePrefix), qPrintable(closeSuffix)); break; + } //end switch(lastid) + switch (id) { //Print the id of the opened page + case ID_PAGE_SETUP_TEAM : qDebug("%sPAGE_SETUP_TEAM%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_SETUP : qDebug("%sPAGE_SETUP%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_MULTIPLAYER : qDebug("%sPAGE_MULTIPLAYER%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_DEMOS : qDebug("%sPAGE_DEMOS%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_NET : qDebug("%sPAGE_NET%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_NETGAME : qDebug("%sPAGE_NETGAME%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_INFO : qDebug("%sPAGE_INFO%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_MAIN : qDebug("%sPAGE_MAIN%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_GAMESTATS : qDebug("%sPAGE_GAMESTATS%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_SINGLEPLAYER : qDebug("%sPAGE_SINGLEPLAYER%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_TRAINING : qDebug("%sPAGE_TRAINING%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_SELECTWEAPON : qDebug("%sPAGE_SELECTWEAPON%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_NETSERVER : qDebug("%sPAGE_NETSERVER%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_INGAME : qDebug("%sPAGE_INGAME%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_ROOMSLIST : qDebug("%sPAGE_ROOMSLIST%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_CONNECTING : qDebug("%sPAGE_CONNECTING%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_SCHEME : qDebug("%sPAGE_SCHEME%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_ADMIN : qDebug("%sPAGE_ADMIN%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_NETTYPE : qDebug("%sPAGE_NETTYPE%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_CAMPAIGN : qDebug("%sPAGE_CAMPAIGN%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_DRAWMAP : qDebug("%sPAGE_DRAWMAP%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_DATADOWNLOAD : qDebug("%sPAGE_DATADOWNLOAD%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_FEEDBACK : qDebug("%sPAGE_FEEDBACK%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case ID_PAGE_VIDEOS : qDebug("%sPAGE_VIDEOS%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + case MAX_PAGE : qDebug("%sMAX_PAGE%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + default : qDebug("%sUNKNOWN PAGE%s", qPrintable(openPrefix), qPrintable(openSuffix)); break; + } //end switch(id) + if (id == ID_PAGE_DATADOWNLOAD) { ui.pageDataDownload->fetchList(); @@ -615,16 +681,6 @@ { ui.pageOptions->setTeamOptionsEnabled(true); } - - if (id == ID_PAGE_SETUP) - { - config->reloadValues(); - } - - if (id == ID_PAGE_VIDEOS ) - { - config->reloadVideosValues(); - } } void HWForm::GoToPage(int id) @@ -969,37 +1025,26 @@ void HWForm::NetPassword(const QString & nick) { - int passLength = config->value("net/passwordlength", 0).toInt(); - QString hash = config->value("net/passwordhash", "").toString(); + //Get hashes + QString hash = config->value("net/passwordhash", "").toString(); + QString temphash = config->value("net/temppasswordhash", "").toString(); + + //Check them - // If the password is blank, ask the user to enter one in - if (passLength == 0) - { - HWPasswordDialog * hpd = new HWPasswordDialog(this, tr("Your nickname %1 is\nregistered on Hedgewars.org\nPlease provide your password below\nor pick another nickname in game config:").arg(nick)); - hpd->cbSave->setChecked(config->value("net/savepassword", true).toBool()); - if (hpd->exec() != QDialog::Accepted) - { - ForcedDisconnect(tr("No password supplied.")); - delete hpd; - return; - } - - QString password = hpd->lePassword->text(); - hash = QCryptographicHash::hash(password.toUtf8(), QCryptographicHash::Md5).toHex(); - - bool save = hpd->cbSave->isChecked(); - config->setValue("net/savepassword", save); - if (save) // user wants to save password - { - config->setValue("net/passwordhash", hash); - config->setValue("net/passwordlength", password.size()); - config->setNetPasswordLength(password.size()); - } - - delete hpd; + if (temphash.isEmpty() && hash.isEmpty()) { //If the user enters a registered nick with no password, sends a bogus hash + hwnet->SendPasswordHash("THISISNOHASH"); + } + else if (temphash.isEmpty()) { //Send saved hash as default + hwnet->SendPasswordHash(hash); + } + else { //Send the hash + hwnet->SendPasswordHash(temphash); } - hwnet->SendPasswordHash(hash); + //Remove temporary hash from config + QString key = "net/temppasswordhash"; + config->setValue(key, ""); + config->remove(key); } void HWForm::NetNickTaken(const QString & nick) @@ -1084,7 +1129,7 @@ //connect(ui.pageNetGame->BtnBack, SIGNAL(clicked()), hwnet, SLOT(partRoom())); ui.pageRoomsList->chatWidget->setUsersModel(hwnet->lobbyPlayersModel()); - ui.pageNetGame->pChatWidget->setUsersModel(hwnet->roomPlayersModel()); + ui.pageNetGame->chatWidget->setUsersModel(hwnet->roomPlayersModel()); // rooms list page stuff ui.pageRoomsList->setModel(hwnet->roomsListModel()); @@ -1113,26 +1158,26 @@ // net page stuff connect(hwnet, SIGNAL(chatStringFromNet(const QString&)), - ui.pageNetGame->pChatWidget, SLOT(onChatString(const QString&)), Qt::QueuedConnection); + ui.pageNetGame->chatWidget, SLOT(onChatString(const QString&)), Qt::QueuedConnection); connect(hwnet, SIGNAL(chatStringFromMe(const QString&)), - ui.pageNetGame->pChatWidget, SLOT(onChatString(const QString&)), Qt::QueuedConnection); + ui.pageNetGame->chatWidget, SLOT(onChatString(const QString&)), Qt::QueuedConnection); connect(hwnet, SIGNAL(roomMaster(bool)), - ui.pageNetGame->pChatWidget, SLOT(adminAccess(bool)), Qt::QueuedConnection); - connect(ui.pageNetGame->pChatWidget, SIGNAL(chatLine(const QString&)), + ui.pageNetGame->chatWidget, SLOT(adminAccess(bool)), Qt::QueuedConnection); + connect(ui.pageNetGame->chatWidget, SIGNAL(chatLine(const QString&)), hwnet, SLOT(chatLineToNet(const QString&))); connect(ui.pageNetGame->BtnGo, SIGNAL(clicked()), hwnet, SLOT(ToggleReady())); connect(hwnet, SIGNAL(setMyReadyStatus(bool)), ui.pageNetGame, SLOT(setReadyStatus(bool)), Qt::QueuedConnection); // chat widget actions - connect(ui.pageNetGame->pChatWidget, SIGNAL(kick(const QString&)), + connect(ui.pageNetGame->chatWidget, SIGNAL(kick(const QString&)), hwnet, SLOT(kickPlayer(const QString&))); - connect(ui.pageNetGame->pChatWidget, SIGNAL(ban(const QString&)), + connect(ui.pageNetGame->chatWidget, SIGNAL(ban(const QString&)), hwnet, SLOT(banPlayer(const QString&))); - connect(ui.pageNetGame->pChatWidget, SIGNAL(info(const QString&)), + connect(ui.pageNetGame->chatWidget, SIGNAL(info(const QString&)), hwnet, SLOT(infoPlayer(const QString&))); - connect(ui.pageNetGame->pChatWidget, SIGNAL(follow(const QString&)), + connect(ui.pageNetGame->chatWidget, SIGNAL(follow(const QString&)), hwnet, SLOT(followPlayer(const QString&))); connect(ui.pageRoomsList->chatWidget, SIGNAL(kick(const QString&)), hwnet, SLOT(kickPlayer(const QString&))); @@ -1155,9 +1200,9 @@ // nick list stuff connect(hwnet, SIGNAL(nickAdded(const QString&, bool)), - ui.pageNetGame->pChatWidget, SLOT(nickAdded(const QString&, bool)), Qt::QueuedConnection); + ui.pageNetGame->chatWidget, SLOT(nickAdded(const QString&, bool)), Qt::QueuedConnection); connect(hwnet, SIGNAL(nickRemoved(const QString&)), - ui.pageNetGame->pChatWidget, SLOT(nickRemoved(const QString&)), Qt::QueuedConnection); + ui.pageNetGame->chatWidget, SLOT(nickRemoved(const QString&)), Qt::QueuedConnection); connect(hwnet, SIGNAL(nickAddedLobby(const QString&, bool)), ui.pageRoomsList->chatWidget, SLOT(nickAdded(const QString&, bool)), Qt::QueuedConnection); connect(hwnet, SIGNAL(nickRemovedLobby(const QString&)), @@ -1198,24 +1243,88 @@ connect(hwnet, SIGNAL(paramChanged(const QString &, const QStringList &)), ui.pageNetGame->pGameCFG, SLOT(setParam(const QString &, const QStringList &))); connect(ui.pageNetGame->pGameCFG, SIGNAL(paramChanged(const QString &, const QStringList &)), hwnet, SLOT(onParamChanged(const QString &, const QStringList &))); connect(hwnet, SIGNAL(configAsked()), ui.pageNetGame->pGameCFG, SLOT(fullNetConfig())); - - while (nick.isEmpty()) + +//nick and pass stuff + + //remove temppasswordhash just in case + config->value("net/temppasswordhash", ""); + config->remove("net/temppasswordhash"); + + //initialize + QString hash = config->value("net/passwordhash", "").toString(); + QString temphash = config->value("net/temppasswordhash", "").toString(); + QString nickname = config->value("net/nick", "").toString(); + QString password; + + if (nickname.isEmpty() || hash.isEmpty()) { //if something from login is missing, start dialog loop + + while (nickname.isEmpty() || (hash.isEmpty() && temphash.isEmpty())) //while a nickname, or both hashes are missing { - nick = QInputDialog::getText(this, - QObject::tr("Nickname"), - QObject::tr("Please enter your nickname"), - QLineEdit::Normal, - QDir::home().dirName()); - config->setValue("net/nick",nick); + //open dialog + HWPasswordDialog * hpd = new HWPasswordDialog(this); + hpd->cbSave->setChecked(config->value("net/savepassword", true).toBool()); + + //if nickname is present, put it into the field + if (!nickname.isEmpty()) { + hpd->leNickname->setText(nickname); + hpd->lePassword->setFocus(); + } + + //if dialog close, create an error message + if (hpd->exec() != QDialog::Accepted) + { + ForcedDisconnect(tr("Login info not supplied.")); + delete hpd; + return; + } + + //set nick and pass from the dialog + nickname = hpd->leNickname->text(); + password = hpd->lePassword->text(); + + //calculate temphash and set it into config + temphash = QCryptographicHash::hash(password.toUtf8(), QCryptographicHash::Md5).toHex(); + config->setValue("net/temppasswordhash", temphash); + + //if user wants to save password + bool save = hpd->cbSave->isChecked(); + config->setValue("net/savepassword", save); + if (save) // user wants to save password + { + config->setValue("net/passwordhash", temphash); + config->setValue("net/passwordlength", password.size()); + config->setNetPasswordLength(password.size()); + } + + delete hpd; + + + //update nickname + config->setValue("net/nick", nickname); config->updNetNick(); + + //and all the variables + hash = config->value("net/passwordhash", "").toString(); + temphash = config->value("net/temppasswordhash", "").toString(); + nickname = config->value("net/nick", "").toString(); + } + + + //if pass is none (hash is generated anyway), remove the hash + if (password.size() <= 0) { + config->setValue("net/temppasswordhash", ""); + config->remove("net/temppasswordhash"); + } } - ui.pageRoomsList->setUser(nick); - ui.pageNetGame->setUser(nick); + ui.pageRoomsList->setUser(nickname); + ui.pageNetGame->setUser(nickname); - hwnet->Connect(hostName, port, nick); + hwnet->Connect(hostName, port, nickname); } + + void HWForm::NetConnect() { HWHostPortDialog * hpd = new HWHostPortDialog(this); @@ -1303,7 +1412,7 @@ void HWForm::NetGameEnter() { - ui.pageNetGame->pChatWidget->clear(); + ui.pageNetGame->chatWidget->clear(); GoToPage(ID_PAGE_NETGAME); } diff -r f781204831ab -r 555a6e06cb33 QTfrontend/hwform.h --- a/QTfrontend/hwform.h Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/hwform.h Tue Dec 04 01:52:14 2012 +0100 @@ -61,7 +61,6 @@ HWForm(QWidget *parent = 0, QString styleSheet = ""); Ui_HWForm ui; static GameUIConfig * config; - static QSettings * gameSettings; // Same file GameUIConfig points to but without the baggage. Needs sync() calls if you want to get GameUIConfig changes though void updateXfire(); void PlayDemoQuick(const QString & demofilename); void exit(); @@ -178,8 +177,8 @@ ID_PAGE_DRAWMAP , ID_PAGE_DATADOWNLOAD , ID_PAGE_FEEDBACK , - ID_PAGE_VIDEOS, - MAX_PAGE + ID_PAGE_VIDEOS , + MAX_PAGE }; QPointer game; QPointer pnetserver; diff -r f781204831ab -r 555a6e06cb33 QTfrontend/main.cpp --- a/QTfrontend/main.cpp Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/main.cpp Tue Dec 04 01:52:14 2012 +0100 @@ -90,9 +90,9 @@ bool checkForDir(const QString & dir) { - QDir tmpdir; - if (!tmpdir.exists(dir)) - if (!tmpdir.mkdir(dir)) + QDir tmpdir(dir); + if (!tmpdir.exists()) + if (!tmpdir.mkpath(dir)) { QMessageBox directoryMsg(QApplication::activeWindow()); directoryMsg.setIcon(QMessageBox::Warning); @@ -105,8 +105,37 @@ return true; } +bool checkForFile(const QString & file) +{ + QFile tmpfile(file); + if (!tmpfile.exists()) + return tmpfile.open(QFile::WriteOnly); + else + return true; +} + +#ifdef __APPLE__ +static CocoaInitializer *cocoaInit = NULL; +// Function to be called at end of program's termination on OS X to release +// the NSAutoReleasePool contained within the CocoaInitializer. +void releaseCocoaPool(void) +{ + if (cocoaInit != NULL) + { + delete cocoaInit; + cocoaInit = NULL; + } +} +#endif + int main(int argc, char *argv[]) { +#ifdef __APPLE__ + // This creates the autoreleasepool that prevents leaking, and destroys it only on exit + cocoaInit = new CocoaInitializer(); + atexit(releaseCocoaPool); +#endif + HWApplication app(argc, argv); FileEngineHandler engine(argv[0]); @@ -232,6 +261,8 @@ engine.setWriteDir(cfgdir->absolutePath()); engine.mountPacks(); + checkForFile("physfs://hedgewars.ini"); + QTranslator Translator; { QSettings settings("physfs://hedgewars.ini", QSettings::IniFormat); @@ -254,10 +285,6 @@ registry_hklm.setValue("Software/Hedgewars/Path", bindir->absolutePath().replace("/", "\\")); } #endif -#ifdef __APPLE__ - // this creates the autoreleasepool that prevents leaking - CocoaInitializer initializer; -#endif QString style = ""; QString fname; diff -r f781204831ab -r 555a6e06cb33 QTfrontend/ui/dialog/bandialog.cpp --- a/QTfrontend/ui/dialog/bandialog.cpp Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/ui/dialog/bandialog.cpp Tue Dec 04 01:52:14 2012 +0100 @@ -30,7 +30,7 @@ cbTime->addItem(tr("3 days"), 72 * 60 * 60); cbTime->addItem(tr("7 days"), 168 * 60 * 60); cbTime->addItem(tr("14 days"), 336 * 60 * 60); - cbTime->addItem(tr("permanent"), 3650 * 60 * 60); + cbTime->addItem(tr("permanent"), 3650 * 24 * 60 * 60); cbTime->setCurrentIndex(0); formLayout->addRow(tr("IP"), rbIP); diff -r f781204831ab -r 555a6e06cb33 QTfrontend/ui/dialog/input_password.cpp --- a/QTfrontend/ui/dialog/input_password.cpp Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/ui/dialog/input_password.cpp Tue Dec 04 01:52:14 2012 +0100 @@ -25,28 +25,44 @@ #include "input_password.h" -HWPasswordDialog::HWPasswordDialog(QWidget* parent, const QString & label) : QDialog(parent) +HWPasswordDialog::HWPasswordDialog(QWidget* parent) : QDialog(parent) { - setWindowTitle(tr("Password")); + setWindowTitle(tr("Login")); + + QString titleLabelText = "To connect to the server, please log in.\n\nIf you don't have an account on www.hedgewars.org,\njust enter your nickname."; + QString nickLabelText = "Nickname:"; + QString passLabelText = "Password:"; QGridLayout * layout = new QGridLayout(this); - QLabel * lbLabel = new QLabel(this); - lbLabel->setText(label); - layout->addWidget(lbLabel, 0, 0); + QLabel * titleLabel = new QLabel(this); + titleLabel->setText(titleLabelText); + layout->addWidget(titleLabel, 0, 0); + + QLabel * nickLabel = new QLabel(this); + nickLabel->setText(nickLabelText); + layout->addWidget(nickLabel, 1, 0); + + leNickname = new QLineEdit(this); + leNickname->setEchoMode(QLineEdit::Normal); + layout->addWidget(leNickname, 2, 0); + + QLabel * passLabel = new QLabel(this); + passLabel->setText(passLabelText); + layout->addWidget(passLabel, 3, 0); lePassword = new QLineEdit(this); lePassword->setEchoMode(QLineEdit::Password); - layout->addWidget(lePassword, 1, 0); + layout->addWidget(lePassword, 4, 0); cbSave = new QCheckBox(this); cbSave->setText(QCheckBox::tr("Save password")); - layout->addWidget(cbSave, 2, 0); + layout->addWidget(cbSave, 5, 0); QDialogButtonBox* dbbButtons = new QDialogButtonBox(this); QPushButton * pbOK = dbbButtons->addButton(QDialogButtonBox::Ok); QPushButton * pbCancel = dbbButtons->addButton(QDialogButtonBox::Cancel); - layout->addWidget(dbbButtons, 3, 0); + layout->addWidget(dbbButtons, 6, 0); connect(pbOK, SIGNAL(clicked()), this, SLOT(accept())); connect(pbCancel, SIGNAL(clicked()), this, SLOT(reject())); diff -r f781204831ab -r 555a6e06cb33 QTfrontend/ui/dialog/input_password.h --- a/QTfrontend/ui/dialog/input_password.h Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/ui/dialog/input_password.h Tue Dec 04 01:52:14 2012 +0100 @@ -28,9 +28,10 @@ { Q_OBJECT public: - HWPasswordDialog(QWidget* parent, const QString & label); + HWPasswordDialog(QWidget* parent); QLineEdit* lePassword; + QLineEdit* leNickname; QCheckBox* cbSave; }; diff -r f781204831ab -r 555a6e06cb33 QTfrontend/ui/page/AbstractPage.cpp --- a/QTfrontend/ui/page/AbstractPage.cpp Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/ui/page/AbstractPage.cpp Tue Dec 04 01:52:14 2012 +0100 @@ -41,8 +41,9 @@ QGridLayout * pageLayout = new QGridLayout(this); // stretch grid space for body and footer - pageLayout->setColumnStretch(0,0); - pageLayout->setColumnStretch(1,1); + pageLayout->setColumnStretch(0,1); + pageLayout->setColumnStretch(1,2); + pageLayout->setColumnStretch(2,1); pageLayout->setRowStretch(0,1); pageLayout->setRowStretch(1,0); diff -r f781204831ab -r 555a6e06cb33 QTfrontend/ui/page/pageadmin.cpp --- a/QTfrontend/ui/page/pageadmin.cpp Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/ui/page/pageadmin.cpp Tue Dec 04 01:52:14 2012 +0100 @@ -156,7 +156,7 @@ void PageAdmin::onAddClicked() { - BanDialog dialog; + BanDialog dialog(this); if(dialog.exec()) { diff -r f781204831ab -r 555a6e06cb33 QTfrontend/ui/page/pagemain.cpp --- a/QTfrontend/ui/page/pagemain.cpp Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/ui/page/pagemain.cpp Tue Dec 04 01:52:14 2012 +0100 @@ -115,7 +115,7 @@ } else { - setDefautDescription(QLabel::tr("This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!")); + setDefautDescription(QLabel::tr("This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!")); } } diff -r f781204831ab -r 555a6e06cb33 QTfrontend/ui/page/pagenetgame.cpp --- a/QTfrontend/ui/page/pagenetgame.cpp Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/ui/page/pagenetgame.cpp Tue Dec 04 01:52:14 2012 +0100 @@ -37,10 +37,10 @@ pageLayout->setColumnStretch(1, 50); // chatwidget - pChatWidget = new HWChatWidget(this, m_gameSettings, true); - pChatWidget->setShowFollow(false); // don't show follow in nicks' context menus - pChatWidget->setIgnoreListKick(true); // kick ignored players automatically - pageLayout->addWidget(pChatWidget, 2, 0, 1, 2); + chatWidget = new HWChatWidget(this, true); + chatWidget->setShowFollow(false); // don't show follow in nicks' context menus + chatWidget->setIgnoreListKick(true); // kick ignored players automatically + pageLayout->addWidget(chatWidget, 2, 0, 1, 2); pageLayout->setRowStretch(1, 100); pageLayout->setRowStretch(2, 100); @@ -96,10 +96,8 @@ connect(BtnUpdate, SIGNAL(clicked()), this, SLOT(onUpdateClick())); } -PageNetGame::PageNetGame(QWidget* parent, QSettings * gameSettings) : AbstractPage(parent) +PageNetGame::PageNetGame(QWidget* parent) : AbstractPage(parent) { - m_gameSettings = gameSettings; - initPage(); QMenu * menu = new QMenu(BtnMaster); @@ -113,24 +111,23 @@ menu->addAction(restrictTeamAdds); BtnMaster->setMenu(menu); - } void PageNetGame::displayError(const QString & message) { - pChatWidget->displayError(message); + chatWidget->displayError(message); } void PageNetGame::displayNotice(const QString & message) { - pChatWidget->displayNotice(message); + chatWidget->displayNotice(message); } void PageNetGame::displayWarning(const QString & message) { - pChatWidget->displayWarning(message); + chatWidget->displayWarning(message); } @@ -178,5 +175,5 @@ void PageNetGame::setUser(const QString & nickname) { - pChatWidget->setUser(nickname); + chatWidget->setUser(nickname); } diff -r f781204831ab -r 555a6e06cb33 QTfrontend/ui/page/pagenetgame.h --- a/QTfrontend/ui/page/pagenetgame.h Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/ui/page/pagenetgame.h Tue Dec 04 01:52:14 2012 +0100 @@ -32,7 +32,7 @@ Q_OBJECT public: - PageNetGame(QWidget* parent, QSettings * gameSettings); + PageNetGame(QWidget* parent); /** * Sets the room name to display. @@ -52,7 +52,7 @@ QAction * restrictJoins; QAction * restrictTeamAdds; - HWChatWidget* pChatWidget; + HWChatWidget* chatWidget; TeamSelWidget* pNetTeamsWidget; GameCFGWidget* pGameCFG; @@ -72,8 +72,6 @@ QLayout * footerLayoutDefinition(); void connectSignals(); - QSettings * m_gameSettings; - HistoryLineEdit * leRoomName; QPushButton * btnSetup; }; diff -r f781204831ab -r 555a6e06cb33 QTfrontend/ui/page/pageoptions.cpp --- a/QTfrontend/ui/page/pageoptions.cpp Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/ui/page/pageoptions.cpp Tue Dec 04 01:52:14 2012 +0100 @@ -33,10 +33,12 @@ #include #include "pageoptions.h" +#include "gameuiconfig.h" #include "hwconsts.h" #include "fpsedit.h" #include "igbox.h" #include "DataManager.h" +#include "LibavInteraction.h" // TODO cleanup QLayout * PageOptions::bodyLayoutDefinition() @@ -50,6 +52,11 @@ tabs->addTab(page1, tr("General")); tabs->addTab(page2, tr("Advanced")); +#ifdef VIDEOREC + QWidget * page3 = new QWidget(this); + tabs->addTab(page3, tr("Video Recording")); +#endif + { // page 1 QGridLayout * page1Layout = new QGridLayout(page1); //gbTBLayout->setMargin(0); @@ -477,6 +484,121 @@ page2Layout->addWidget(new QWidget(this), 2, 0); } +#ifdef VIDEOREC + { // page 3 + QGridLayout * page3Layout = new QGridLayout(page3); + + IconedGroupBox* pOptionsGroup = new IconedGroupBox(this); + pOptionsGroup->setIcon(QIcon(":/res/Settings.png")); // FIXME + pOptionsGroup->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + pOptionsGroup->setTitle(QGroupBox::tr("Video recording options")); + QGridLayout * pOptLayout = new QGridLayout(pOptionsGroup); + + // label for format + QLabel *labelFormat = new QLabel(pOptionsGroup); + labelFormat->setText(QLabel::tr("Format")); + pOptLayout->addWidget(labelFormat, 0, 0); + + // list of supported formats + comboAVFormats = new QComboBox(pOptionsGroup); + pOptLayout->addWidget(comboAVFormats, 0, 1, 1, 4); + LibavInteraction::instance().fillFormats(comboAVFormats); + + // separator + QFrame * hr = new QFrame(pOptionsGroup); + hr->setFrameStyle(QFrame::HLine); + hr->setLineWidth(3); + hr->setFixedHeight(10); + pOptLayout->addWidget(hr, 1, 0, 1, 5); + + // label for audio codec + QLabel *labelACodec = new QLabel(pOptionsGroup); + labelACodec->setText(QLabel::tr("Audio codec")); + pOptLayout->addWidget(labelACodec, 2, 0); + + // list of supported audio codecs + comboAudioCodecs = new QComboBox(pOptionsGroup); + pOptLayout->addWidget(comboAudioCodecs, 2, 1, 1, 3); + + // checkbox 'record audio' + checkRecordAudio = new QCheckBox(pOptionsGroup); + checkRecordAudio->setText(QCheckBox::tr("Record audio")); + pOptLayout->addWidget(checkRecordAudio, 2, 4); + + // separator + hr = new QFrame(pOptionsGroup); + hr->setFrameStyle(QFrame::HLine); + hr->setLineWidth(3); + hr->setFixedHeight(10); + pOptLayout->addWidget(hr, 3, 0, 1, 5); + + // label for video codec + QLabel *labelVCodec = new QLabel(pOptionsGroup); + labelVCodec->setText(QLabel::tr("Video codec")); + pOptLayout->addWidget(labelVCodec, 4, 0); + + // list of supported video codecs + comboVideoCodecs = new QComboBox(pOptionsGroup); + pOptLayout->addWidget(comboVideoCodecs, 4, 1, 1, 4); + + // label for resolution + QLabel *labelRes = new QLabel(pOptionsGroup); + labelRes->setText(QLabel::tr("Resolution")); + pOptLayout->addWidget(labelRes, 5, 0); + + // width + widthEdit = new QLineEdit(pOptionsGroup); + widthEdit->setValidator(new QIntValidator(this)); + pOptLayout->addWidget(widthEdit, 5, 1); + + // x + QLabel *labelX = new QLabel(pOptionsGroup); + labelX->setText("X"); + pOptLayout->addWidget(labelX, 5, 2); + + // height + heightEdit = new QLineEdit(pOptionsGroup); + heightEdit->setValidator(new QIntValidator(pOptionsGroup)); + pOptLayout->addWidget(heightEdit, 5, 3); + + // checkbox 'use game resolution' + checkUseGameRes = new QCheckBox(pOptionsGroup); + checkUseGameRes->setText(QCheckBox::tr("Use game resolution")); + pOptLayout->addWidget(checkUseGameRes, 5, 4); + + // label for framerate + QLabel *labelFramerate = new QLabel(pOptionsGroup); + labelFramerate->setText(QLabel::tr("Framerate")); + pOptLayout->addWidget(labelFramerate, 6, 0); + + framerateBox = new QComboBox(pOptionsGroup); + framerateBox->addItem("24 fps", 24); + framerateBox->addItem("25 fps", 25); + framerateBox->addItem("30 fps", 30); + framerateBox->addItem("50 fps", 50); + framerateBox->addItem("60 fps", 60); + pOptLayout->addWidget(framerateBox, 6, 1); + + // label for Bitrate + QLabel *labelBitrate = new QLabel(pOptionsGroup); + labelBitrate->setText(QLabel::tr("Bitrate (Kbps)")); + pOptLayout->addWidget(labelBitrate, 6, 2); + + // bitrate + bitrateBox = new QSpinBox(pOptionsGroup); + bitrateBox->setRange(100, 5000); + bitrateBox->setSingleStep(100); + pOptLayout->addWidget(bitrateBox, 6, 3); + + // button 'set default options' + btnDefaults = new QPushButton(pOptionsGroup); + btnDefaults->setText(QPushButton::tr("Set default options")); + btnDefaults->setWhatsThis(QPushButton::tr("Restore default coding parameters")); + pOptLayout->addWidget(btnDefaults, 7, 0, 1, 5); + + page3Layout->addWidget(pOptionsGroup, 1, 0); + } +#endif previousQuality = this->SLQuality->value(); previousResolutionIndex = this->CBResolution->currentIndex(); @@ -492,6 +614,13 @@ void PageOptions::connectSignals() { +#ifdef VIDEOREC + connect(checkUseGameRes, SIGNAL(stateChanged(int)), this, SLOT(changeUseGameRes(int))); + connect(checkRecordAudio, SIGNAL(stateChanged(int)), this, SLOT(changeRecordAudio(int))); + connect(comboAVFormats, SIGNAL(currentIndexChanged(int)), this, SLOT(changeAVFormat(int))); + connect(btnDefaults, SIGNAL(clicked()), this, SLOT(setDefaultOptions())); +#endif + connect(SLQuality, SIGNAL(valueChanged(int)), this, SLOT(setQuality(int))); connect(CBResolution, SIGNAL(currentIndexChanged(int)), this, SLOT(setResolution(int))); connect(CBFullscreen, SIGNAL(stateChanged(int)), this, SLOT(setFullscreen(int))); @@ -500,7 +629,7 @@ connect(CBSavePassword, SIGNAL(stateChanged(int)), this, SLOT(savePwdChanged(int))); } -PageOptions::PageOptions(QWidget* parent) : AbstractPage(parent) +PageOptions::PageOptions(QWidget* parent) : AbstractPage(parent), config(0) { initPage(); } @@ -619,3 +748,128 @@ leProxyLogin->setEnabled(b); leProxyPassword->setEnabled(b); } + +// Video Recording + +void PageOptions::setConfig(GameUIConfig * config) +{ + this->config = config; +} + +// user changed file format, we need to update list of codecs +void PageOptions::changeAVFormat(int index) +{ + // remember selected codecs + QString prevVCodec = videoCodec(); + QString prevACodec = audioCodec(); + + // clear lists of codecs + comboVideoCodecs->clear(); + comboAudioCodecs->clear(); + + // get list of codecs for specified format + LibavInteraction::instance().fillCodecs(comboAVFormats->itemData(index).toString(), comboVideoCodecs, comboAudioCodecs); + + // disable audio if there is no audio codec + if (comboAudioCodecs->count() == 0) + { + checkRecordAudio->setChecked(false); + checkRecordAudio->setEnabled(false); + } + else + checkRecordAudio->setEnabled(true); + + // restore selected codecs if possible + int iVCodec = comboVideoCodecs->findData(prevVCodec); + if (iVCodec != -1) + comboVideoCodecs->setCurrentIndex(iVCodec); + int iACodec = comboAudioCodecs->findData(prevACodec); + if (iACodec != -1) + comboAudioCodecs->setCurrentIndex(iACodec); +} + +// user switched checkbox 'use game resolution' +void PageOptions::changeUseGameRes(int state) +{ + if (state && config) + { + // set resolution to game resolution + QRect resolution = config->vid_Resolution(); + widthEdit->setText(QString::number(resolution.width())); + heightEdit->setText(QString::number(resolution.height())); + } + widthEdit->setEnabled(!state); + heightEdit->setEnabled(!state); +} + +// user switched checkbox 'record audio' +void PageOptions::changeRecordAudio(int state) +{ + comboAudioCodecs->setEnabled(!!state); +} + +void PageOptions::setDefaultCodecs() +{ + // VLC should be able to handle any of these configurations + // Quicktime X only opens the first one + // Windows Media Player TODO + if (tryCodecs("mp4", "libx264", "aac")) + return; + if (tryCodecs("mp4", "libx264", "libfaac")) + return; + if (tryCodecs("mp4", "libx264", "libmp3lame")) + return; + if (tryCodecs("mp4", "libx264", "mp2")) + return; + if (tryCodecs("avi", "libxvid", "libmp3lame")) + return; + if (tryCodecs("avi", "libxvid", "ac3_fixed")) + return; + if (tryCodecs("avi", "libxvid", "mp2")) + return; + if (tryCodecs("avi", "mpeg4", "libmp3lame")) + return; + if (tryCodecs("avi", "mpeg4", "ac3_fixed")) + return; + if (tryCodecs("avi", "mpeg4", "mp2")) + return; + + // this shouldn't happen, just in case + if (tryCodecs("ogg", "libtheora", "libvorbis")) + return; + tryCodecs("ogg", "libtheora", "flac"); +} + +void PageOptions::setDefaultOptions() +{ + framerateBox->setCurrentIndex(2); + bitrateBox->setValue(1000); + checkRecordAudio->setChecked(true); + checkUseGameRes->setChecked(true); + setDefaultCodecs(); +} + +bool PageOptions::tryCodecs(const QString & format, const QString & vcodec, const QString & acodec) +{ + // first we should change format + int iFormat = comboAVFormats->findData(format); + if (iFormat == -1) + return false; + comboAVFormats->setCurrentIndex(iFormat); + // format was changed, so lists of codecs were automatically updated to codecs supported by this format + + // try to find video codec + int iVCodec = comboVideoCodecs->findData(vcodec); + if (iVCodec == -1) + return false; + comboVideoCodecs->setCurrentIndex(iVCodec); + + // try to find audio codec + int iACodec = comboAudioCodecs->findData(acodec); + if (iACodec == -1 && checkRecordAudio->isChecked()) + return false; + if (iACodec != -1) + comboAudioCodecs->setCurrentIndex(iACodec); + + return true; +} diff -r f781204831ab -r 555a6e06cb33 QTfrontend/ui/page/pageoptions.h --- a/QTfrontend/ui/page/pageoptions.h Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/ui/page/pageoptions.h Tue Dec 04 01:52:14 2012 +0100 @@ -21,6 +21,7 @@ #include "AbstractPage.h" +class GameUIConfig; class FPSEdit; class IconedGroupBox; class QSignalMapper; @@ -84,6 +85,28 @@ QLineEdit * leProxyLogin; QLineEdit * leProxyPassword; +#ifdef VIDEOREC + QComboBox *framerateBox; + QSpinBox *bitrateBox; + QLineEdit *widthEdit; + QLineEdit *heightEdit; + QCheckBox *checkUseGameRes; + QCheckBox *checkRecordAudio; + + QString format() + { return comboAVFormats->itemData(comboAVFormats->currentIndex()).toString(); } + + QString videoCodec() + { return comboVideoCodecs->itemData(comboVideoCodecs->currentIndex()).toString(); } + + QString audioCodec() + { return comboAudioCodecs->itemData(comboAudioCodecs->currentIndex()).toString(); } + + void setDefaultCodecs(); + bool tryCodecs(const QString & format, const QString & vcodec, const QString & acodec); + void setConfig(GameUIConfig * config); +#endif + void setTeamOptionsEnabled(bool enabled); signals: @@ -106,6 +129,14 @@ QPushButton *BtnDeleteTeam; QList m_colorButtons; +#ifdef VIDEOREC + QComboBox *comboAVFormats; + QComboBox *comboVideoCodecs; + QComboBox *comboAudioCodecs; + QPushButton *btnDefaults; + GameUIConfig * config; +#endif + private slots: void forceFullscreen(int index); void setFullscreen(int state); @@ -118,6 +149,14 @@ void colorButtonClicked(int i); void onColorModelDataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight); void onProxyTypeChanged(); +#ifdef VIDEOREC + void changeAVFormat(int index); + void changeUseGameRes(int state); + void changeRecordAudio(int state); + + public slots: + void setDefaultOptions(); +#endif }; #endif diff -r f781204831ab -r 555a6e06cb33 QTfrontend/ui/page/pageroomslist.cpp --- a/QTfrontend/ui/page/pageroomslist.cpp Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/ui/page/pageroomslist.cpp Tue Dec 04 01:52:14 2012 +0100 @@ -95,7 +95,7 @@ pageLayout->addLayout(filterLayout, 4, 0, 1, 2); - chatWidget = new HWChatWidget(this, m_gameSettings, false); + chatWidget = new HWChatWidget(this, false); pageLayout->addWidget(chatWidget, 5, 0, 1, 3); pageLayout->setRowStretch(5, 350); @@ -156,11 +156,9 @@ } -PageRoomsList::PageRoomsList(QWidget* parent, QSettings * gameSettings) : +PageRoomsList::PageRoomsList(QWidget* parent) : AbstractPage(parent) { - m_gameSettings = gameSettings; - roomsModel = NULL; stateFilteredModel = NULL; schemeFilteredModel = NULL; @@ -612,13 +610,17 @@ QString("*%1*").arg(CBWeapons->currentText())); } +void PageRoomsList::setSettings(QSettings *settings) +{ + m_gameSettings = settings; +} bool PageRoomsList::restoreHeaderState() { if (!m_gameSettings->contains("frontend/roomslist_header")) return false; return roomsList->horizontalHeader()->restoreState(QByteArray::fromBase64( - (m_gameSettings->value("frontend/roomslist_header").toString().toAscii()))); + (m_gameSettings->value("frontend/roomslist_header").toByteArray()))); } void PageRoomsList::saveHeaderState() diff -r f781204831ab -r 555a6e06cb33 QTfrontend/ui/page/pageroomslist.h --- a/QTfrontend/ui/page/pageroomslist.h Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/ui/page/pageroomslist.h Tue Dec 04 01:52:14 2012 +0100 @@ -32,10 +32,11 @@ Q_OBJECT public: - PageRoomsList(QWidget* parent, QSettings * config); + PageRoomsList(QWidget* parent); void displayError(const QString & message); void displayNotice(const QString & message); void displayWarning(const QString & message); + void setSettings(QSettings * settings); QLineEdit * roomName; QLineEdit * searchText; diff -r f781204831ab -r 555a6e06cb33 QTfrontend/ui/page/pagevideos.cpp --- a/QTfrontend/ui/page/pagevideos.cpp Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/ui/page/pagevideos.cpp Tue Dec 04 01:52:14 2012 +0100 @@ -109,119 +109,6 @@ QGridLayout * pPageLayout = new QGridLayout(); pPageLayout->setColumnStretch(0, 1); pPageLayout->setColumnStretch(1, 2); - pPageLayout->setRowStretch(0, 1); - pPageLayout->setRowStretch(1, 1); - - // options - { - IconedGroupBox* pOptionsGroup = new IconedGroupBox(this); - pOptionsGroup->setIcon(QIcon(":/res/Settings.png")); // FIXME - pOptionsGroup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - pOptionsGroup->setTitle(QGroupBox::tr("Video recording options")); - QGridLayout * pOptLayout = new QGridLayout(pOptionsGroup); - - // label for format - QLabel *labelFormat = new QLabel(pOptionsGroup); - labelFormat->setText(QLabel::tr("Format")); - pOptLayout->addWidget(labelFormat, 0, 0); - - // list of supported formats - comboAVFormats = new QComboBox(pOptionsGroup); - pOptLayout->addWidget(comboAVFormats, 0, 1, 1, 4); - LibavInteraction::instance().fillFormats(comboAVFormats); - - // separator - QFrame * hr = new QFrame(pOptionsGroup); - hr->setFrameStyle(QFrame::HLine); - hr->setLineWidth(3); - hr->setFixedHeight(10); - pOptLayout->addWidget(hr, 1, 0, 1, 5); - - // label for audio codec - QLabel *labelACodec = new QLabel(pOptionsGroup); - labelACodec->setText(QLabel::tr("Audio codec")); - pOptLayout->addWidget(labelACodec, 2, 0); - - // list of supported audio codecs - comboAudioCodecs = new QComboBox(pOptionsGroup); - pOptLayout->addWidget(comboAudioCodecs, 2, 1, 1, 3); - - // checkbox 'record audio' - checkRecordAudio = new QCheckBox(pOptionsGroup); - checkRecordAudio->setText(QCheckBox::tr("Record audio")); - pOptLayout->addWidget(checkRecordAudio, 2, 4); - - // separator - hr = new QFrame(pOptionsGroup); - hr->setFrameStyle(QFrame::HLine); - hr->setLineWidth(3); - hr->setFixedHeight(10); - pOptLayout->addWidget(hr, 3, 0, 1, 5); - - // label for video codec - QLabel *labelVCodec = new QLabel(pOptionsGroup); - labelVCodec->setText(QLabel::tr("Video codec")); - pOptLayout->addWidget(labelVCodec, 4, 0); - - // list of supported video codecs - comboVideoCodecs = new QComboBox(pOptionsGroup); - pOptLayout->addWidget(comboVideoCodecs, 4, 1, 1, 4); - - // label for resolution - QLabel *labelRes = new QLabel(pOptionsGroup); - labelRes->setText(QLabel::tr("Resolution")); - pOptLayout->addWidget(labelRes, 5, 0); - - // width - widthEdit = new QLineEdit(pOptionsGroup); - widthEdit->setValidator(new QIntValidator(this)); - pOptLayout->addWidget(widthEdit, 5, 1); - - // x - QLabel *labelX = new QLabel(pOptionsGroup); - labelX->setText("X"); - pOptLayout->addWidget(labelX, 5, 2); - - // height - heightEdit = new QLineEdit(pOptionsGroup); - heightEdit->setValidator(new QIntValidator(pOptionsGroup)); - pOptLayout->addWidget(heightEdit, 5, 3); - - // checkbox 'use game resolution' - checkUseGameRes = new QCheckBox(pOptionsGroup); - checkUseGameRes->setText(QCheckBox::tr("Use game resolution")); - pOptLayout->addWidget(checkUseGameRes, 5, 4); - - // label for framerate - QLabel *labelFramerate = new QLabel(pOptionsGroup); - labelFramerate->setText(QLabel::tr("Framerate")); - pOptLayout->addWidget(labelFramerate, 6, 0); - - // framerate - framerateBox = new QSpinBox(pOptionsGroup); - framerateBox->setRange(1, 200); - framerateBox->setSingleStep(1); - pOptLayout->addWidget(framerateBox, 6, 1); - - // label for Bitrate - QLabel *labelBitrate = new QLabel(pOptionsGroup); - labelBitrate->setText(QLabel::tr("Bitrate (Kbps)")); - pOptLayout->addWidget(labelBitrate, 6, 2); - - // bitrate - bitrateBox = new QSpinBox(pOptionsGroup); - bitrateBox->setRange(100, 5000); - bitrateBox->setSingleStep(100); - pOptLayout->addWidget(bitrateBox, 6, 3); - - // button 'set default options' - btnDefaults = new QPushButton(pOptionsGroup); - btnDefaults->setText(QPushButton::tr("Set default options")); - btnDefaults->setWhatsThis(QPushButton::tr("Restore default coding parameters")); - pOptLayout->addWidget(btnDefaults, 7, 0, 1, 5); - - pPageLayout->addWidget(pOptionsGroup, 1, 0); - } // list of videos { @@ -257,7 +144,7 @@ box->addWidget(filesTable); box->addWidget(btnOpenDir); - pPageLayout->addWidget(pTableGroup, 0, 1, 2, 1); + pPageLayout->addWidget(pTableGroup, 0, 1); } // description @@ -267,7 +154,6 @@ pDescGroup->setTitle(QGroupBox::tr("Description")); QVBoxLayout* pDescLayout = new QVBoxLayout(pDescGroup); - QHBoxLayout* pTopDescLayout = new QHBoxLayout(0); // picture and text QHBoxLayout* pBottomDescLayout = new QHBoxLayout(0); // buttons // label with thumbnail picture @@ -282,7 +168,6 @@ "border-radius: 4px;" "}" ); clearThumbnail(); - pTopDescLayout->addWidget(labelThumbnail, 2); // label with file description labelDesc = new QLabel(pDescGroup); @@ -293,7 +178,8 @@ Qt::LinksAccessibleByKeyboard); labelDesc->setTextFormat(Qt::RichText); labelDesc->setOpenExternalLinks(true); - pTopDescLayout->addWidget(labelDesc, 1); + labelDesc->setMinimumSize(ThumbnailSize); + //pTopDescLayout->addWidget(labelDesc, 1); // buttons: play and delete btnPlay = new QPushButton(QPushButton::tr("Play"), pDescGroup); @@ -310,7 +196,9 @@ pBottomDescLayout->addWidget(btnToYouTube); pDescLayout->addStretch(1); - pDescLayout->addLayout(pTopDescLayout, 0); + pDescLayout->addWidget(labelThumbnail, 0); + pDescLayout->addStretch(1); + pDescLayout->addWidget(labelDesc, 0); pDescLayout->addStretch(1); pDescLayout->addLayout(pBottomDescLayout, 0); @@ -327,10 +215,6 @@ void PageVideos::connectSignals() { - connect(checkUseGameRes, SIGNAL(stateChanged(int)), this, SLOT(changeUseGameRes(int))); - connect(checkRecordAudio, SIGNAL(stateChanged(int)), this, SLOT(changeRecordAudio(int))); - connect(comboAVFormats, SIGNAL(currentIndexChanged(int)), this, SLOT(changeAVFormat(int))); - connect(btnDefaults, SIGNAL(clicked()), this, SLOT(setDefaultOptions())); connect(filesTable, SIGNAL(cellDoubleClicked(int, int)), this, SLOT(cellDoubleClicked(int, int))); connect(filesTable, SIGNAL(cellChanged(int,int)), this, SLOT(cellChanged(int, int))); connect(filesTable, SIGNAL(currentCellChanged(int,int,int,int)), this, SLOT(currentCellChanged())); @@ -362,124 +246,6 @@ startEncoding(); // this is for videos recorded from demos which were executed directly (without frontend) } -// user changed file format, we need to update list of codecs -void PageVideos::changeAVFormat(int index) -{ - // remember selected codecs - QString prevVCodec = videoCodec(); - QString prevACodec = audioCodec(); - - // clear lists of codecs - comboVideoCodecs->clear(); - comboAudioCodecs->clear(); - - // get list of codecs for specified format - LibavInteraction::instance().fillCodecs(comboAVFormats->itemData(index).toString(), comboVideoCodecs, comboAudioCodecs); - - // disable audio if there is no audio codec - if (comboAudioCodecs->count() == 0) - { - checkRecordAudio->setChecked(false); - checkRecordAudio->setEnabled(false); - } - else - checkRecordAudio->setEnabled(true); - - // restore selected codecs if possible - int iVCodec = comboVideoCodecs->findData(prevVCodec); - if (iVCodec != -1) - comboVideoCodecs->setCurrentIndex(iVCodec); - int iACodec = comboAudioCodecs->findData(prevACodec); - if (iACodec != -1) - comboAudioCodecs->setCurrentIndex(iACodec); -} - -// user switched checkbox 'use game resolution' -void PageVideos::changeUseGameRes(int state) -{ - if (state && config) - { - // set resolution to game resolution - QRect resolution = config->vid_Resolution(); - widthEdit->setText(QString::number(resolution.width())); - heightEdit->setText(QString::number(resolution.height())); - } - widthEdit->setEnabled(!state); - heightEdit->setEnabled(!state); -} - -// user switched checkbox 'record audio' -void PageVideos::changeRecordAudio(int state) -{ - comboAudioCodecs->setEnabled(!!state); -} - -void PageVideos::setDefaultCodecs() -{ - // VLC should be able to handle any of these configurations - // Quicktime X only opens the first one - // Windows Media Player TODO - if (tryCodecs("mp4", "libx264", "aac")) - return; - if (tryCodecs("mp4", "libx264", "libfaac")) - return; - if (tryCodecs("mp4", "libx264", "libmp3lame")) - return; - if (tryCodecs("mp4", "libx264", "mp2")) - return; - if (tryCodecs("avi", "libxvid", "libmp3lame")) - return; - if (tryCodecs("avi", "libxvid", "ac3_fixed")) - return; - if (tryCodecs("avi", "libxvid", "mp2")) - return; - if (tryCodecs("avi", "mpeg4", "libmp3lame")) - return; - if (tryCodecs("avi", "mpeg4", "ac3_fixed")) - return; - if (tryCodecs("avi", "mpeg4", "mp2")) - return; - - // this shouldn't happen, just in case - if (tryCodecs("ogg", "libtheora", "libvorbis")) - return; - tryCodecs("ogg", "libtheora", "flac"); -} - -void PageVideos::setDefaultOptions() -{ - framerateBox->setValue(30); - bitrateBox->setValue(1000); - checkRecordAudio->setChecked(true); - checkUseGameRes->setChecked(true); - setDefaultCodecs(); -} - -bool PageVideos::tryCodecs(const QString & format, const QString & vcodec, const QString & acodec) -{ - // first we should change format - int iFormat = comboAVFormats->findData(format); - if (iFormat == -1) - return false; - comboAVFormats->setCurrentIndex(iFormat); - // format was changed, so lists of codecs were automatically updated to codecs supported by this format - - // try to find video codec - int iVCodec = comboVideoCodecs->findData(vcodec); - if (iVCodec == -1) - return false; - comboVideoCodecs->setCurrentIndex(iVCodec); - - // try to find audio codec - int iACodec = comboAudioCodecs->findData(acodec); - if (iACodec == -1 && checkRecordAudio->isChecked()) - return false; - if (iACodec != -1) - comboAudioCodecs->setCurrentIndex(iACodec); - - return true; -} - // get file size as string static QString FileSizeStr(const QString & path) { diff -r f781204831ab -r 555a6e06cb33 QTfrontend/ui/page/pagevideos.h --- a/QTfrontend/ui/page/pagevideos.h Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/ui/page/pagevideos.h Tue Dec 04 01:52:14 2012 +0100 @@ -36,24 +36,6 @@ public: PageVideos(QWidget* parent = 0); - QSpinBox *framerateBox; - QSpinBox *bitrateBox; - QLineEdit *widthEdit; - QLineEdit *heightEdit; - QCheckBox *checkUseGameRes; - QCheckBox *checkRecordAudio; - - QString format() - { return comboAVFormats->itemData(comboAVFormats->currentIndex()).toString(); } - - QString videoCodec() - { return comboVideoCodecs->itemData(comboVideoCodecs->currentIndex()).toString(); } - - QString audioCodec() - { return comboAudioCodecs->itemData(comboAudioCodecs->currentIndex()).toString(); } - - void setDefaultCodecs(); - bool tryCodecs(const QString & format, const QString & vcodec, const QString & acodec); void addRecorder(HWRecorder* pRecorder); bool tryQuit(HWForm *form); QString getVideosInProgress(); // get multi-line string with list of videos in progress @@ -83,12 +65,6 @@ GameUIConfig * config; QNetworkAccessManager* netManager; - // options group - QComboBox *comboAVFormats; - QComboBox *comboVideoCodecs; - QComboBox *comboAudioCodecs; - QPushButton *btnDefaults; - // file list group QTableWidget *filesTable; QPushButton *btnOpenDir; @@ -105,10 +81,6 @@ int numRecorders, numUploads; private slots: - void changeAVFormat(int index); - void changeUseGameRes(int state); - void changeRecordAudio(int state); - void setDefaultOptions(); void encodingFinished(bool success); void updateProgress(float value); void cellDoubleClicked(int row, int column); diff -r f781204831ab -r 555a6e06cb33 QTfrontend/ui/widget/chatwidget.cpp --- a/QTfrontend/ui/widget/chatwidget.cpp Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/ui/widget/chatwidget.cpp Tue Dec 04 01:52:14 2012 +0100 @@ -177,7 +177,7 @@ } -HWChatWidget::HWChatWidget(QWidget* parent, QSettings * gameSettings, bool notify) : +HWChatWidget::HWChatWidget(QWidget* parent, bool notify) : QWidget(parent), mainLayout(this) { @@ -187,7 +187,6 @@ m_isAdmin = false; m_autoKickEnabled = false; - if(gameSettings->value("frontend/sound", true).toBool()) { QStringList vpList = QStringList() << "Classic" << "Default" << "Mobster" << "Russian"; @@ -281,6 +280,10 @@ clear(); } +void HWChatWidget::setSettings(QSettings * settings) +{ + gameSettings = settings; +} void HWChatWidget::linkClicked(const QUrl & link) { diff -r f781204831ab -r 555a6e06cb33 QTfrontend/ui/widget/chatwidget.h --- a/QTfrontend/ui/widget/chatwidget.h Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/ui/widget/chatwidget.h Tue Dec 04 01:52:14 2012 +0100 @@ -54,7 +54,7 @@ Q_OBJECT public: - HWChatWidget(QWidget* parent, QSettings * gameSettings, bool notify); + HWChatWidget(QWidget* parent, bool notify); void setIgnoreListKick(bool enabled); ///< automatically kick people on ignore list (if possible) void setShowFollow(bool enabled); static const QString & styleSheet(); @@ -63,6 +63,7 @@ void displayWarning(const QString & message); void setUser(const QString & nickname); void setUsersModel(QAbstractItemModel * model); + void setSettings(QSettings * settings); protected: virtual void dragEnterEvent(QDragEnterEvent * event); diff -r f781204831ab -r 555a6e06cb33 QTfrontend/ui_hwform.cpp --- a/QTfrontend/ui_hwform.cpp Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/ui_hwform.cpp Tue Dec 04 01:52:14 2012 +0100 @@ -60,7 +60,7 @@ centralWidget = new QWidget(HWForm); centralWidget->setObjectName(QString::fromUtf8("centralWidget")); - SetupPages(centralWidget, HWForm); + SetupPages(centralWidget); HWForm->setCentralWidget(centralWidget); @@ -74,7 +74,7 @@ font14 = new QFont("MS Shell Dlg", 14); } -void Ui_HWForm::SetupPages(QWidget *Parent, HWForm *HWForm) +void Ui_HWForm::SetupPages(QWidget *Parent) { Pages = new QStackedLayout(Parent); @@ -93,7 +93,7 @@ pageNet = new PageNet(); Pages->addWidget(pageNet); - pageNetGame = new PageNetGame(Parent, HWForm->gameSettings); + pageNetGame = new PageNetGame(Parent); Pages->addWidget(pageNetGame); pageInfo = new PageInfo(); @@ -120,7 +120,7 @@ pageInGame = new PageInGame(); Pages->addWidget(pageInGame); - pageRoomsList = new PageRoomsList(Parent, HWForm->gameSettings); + pageRoomsList = new PageRoomsList(Parent); Pages->addWidget(pageRoomsList); pageConnecting = new PageConnecting(); diff -r f781204831ab -r 555a6e06cb33 QTfrontend/ui_hwform.h --- a/QTfrontend/ui_hwform.h Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/ui_hwform.h Tue Dec 04 01:52:14 2012 +0100 @@ -86,7 +86,7 @@ void setupUi(HWForm *HWForm); void SetupFonts(); - void SetupPages(QWidget *Parent, HWForm *HWForm); + void SetupPages(QWidget *Parent); }; #endif // UI_HWFORM_H diff -r f781204831ab -r 555a6e06cb33 QTfrontend/util/FileEngine.cpp --- a/QTfrontend/util/FileEngine.cpp Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/util/FileEngine.cpp Tue Dec 04 01:52:14 2012 +0100 @@ -10,8 +10,10 @@ FileEngine::FileEngine(const QString& filename) : m_handle(NULL) + , m_size(0) , m_flags(0) , m_bufferSet(false) + , m_readWrite(false) { setFileName(filename); } @@ -25,7 +27,16 @@ { close(); - if (openMode & QIODevice::WriteOnly) { + if ((openMode & QIODevice::ReadWrite) == QIODevice::ReadWrite) { + m_handle = PHYSFS_openAppend(m_fileName.toUtf8().constData()); + if(m_handle) + { + m_readWrite = true; + seek(0); + } + } + + else if (openMode & QIODevice::WriteOnly) { m_handle = PHYSFS_openWrite(m_fileName.toUtf8().constData()); m_flags = QAbstractFileEngine::WriteOwnerPerm | QAbstractFileEngine::WriteUserPerm | QAbstractFileEngine::FileType; } @@ -76,9 +87,22 @@ return PHYSFS_tell(m_handle); } +bool FileEngine::setSize(qint64 size) +{ + if(size == 0) + { + m_size = 0; + return open(QIODevice::WriteOnly); + } + else + return false; +} + bool FileEngine::seek(qint64 pos) { - return PHYSFS_seek(m_handle, pos) != 0; + bool ok = PHYSFS_seek(m_handle, pos) != 0; + + return ok; } bool FileEngine::isSequential() const @@ -94,12 +118,14 @@ bool FileEngine::mkdir(const QString &dirName, bool createParentDirectories) const { Q_UNUSED(createParentDirectories); + return PHYSFS_mkdir(dirName.toUtf8().constData()) != 0; } bool FileEngine::rmdir(const QString &dirName, bool recurseParentDirectories) const { Q_UNUSED(recurseParentDirectories); + return PHYSFS_delete(dirName.toUtf8().constData()) != 0; } @@ -110,7 +136,7 @@ bool FileEngine::isRelativePath() const { - return true; + return false; } QAbstractFileEngineIterator * FileEngine::beginEntryList(QDir::Filters filters, const QStringList &filterNames) @@ -171,7 +197,6 @@ QDateTime FileEngine::fileTime(FileTime time) const { - switch (time) { case QAbstractFileEngine::ModificationTime: @@ -187,21 +212,21 @@ m_fileName = file.mid(FileEngineHandler::scheme.size()); else m_fileName = file; - PHYSFS_Stat stat; - if (PHYSFS_stat(m_fileName.toUtf8().constData(), &stat) != 0) { + if (PHYSFS_stat(m_fileName.toUtf8().constData(), &stat) != 0) { m_size = stat.filesize; m_date = QDateTime::fromTime_t(stat.modtime); -// _flags |= QAbstractFileEngine::WriteUserPerm; +// m_flags |= QAbstractFileEngine::WriteOwnerPerm; + m_flags |= QAbstractFileEngine::ReadOwnerPerm; m_flags |= QAbstractFileEngine::ReadUserPerm; m_flags |= QAbstractFileEngine::ExistsFlag; + m_flags |= QAbstractFileEngine::LocalDiskFlag; switch (stat.filetype) { case PHYSFS_FILETYPE_REGULAR: m_flags |= QAbstractFileEngine::FileType; break; - case PHYSFS_FILETYPE_DIRECTORY: m_flags |= QAbstractFileEngine::DirectoryType; break; @@ -220,7 +245,16 @@ qint64 FileEngine::read(char *data, qint64 maxlen) { - return PHYSFS_readBytes(m_handle, data, maxlen); + if(m_readWrite) + { + if(pos() == 0) + open(QIODevice::ReadOnly); + else + return -1; + } + + qint64 len = PHYSFS_readBytes(m_handle, data, maxlen); + return len; } qint64 FileEngine::readLine(char *data, qint64 maxlen) @@ -286,7 +320,7 @@ QAbstractFileEngine* FileEngineHandler::create(const QString &filename) const { if (filename.startsWith(scheme)) - return new FileEngine(filename.mid(scheme.size())); + return new FileEngine(filename); else return NULL; } diff -r f781204831ab -r 555a6e06cb33 QTfrontend/util/FileEngine.h --- a/QTfrontend/util/FileEngine.h Fri Nov 30 23:04:49 2012 -0500 +++ b/QTfrontend/util/FileEngine.h Tue Dec 04 01:52:14 2012 +0100 @@ -22,6 +22,7 @@ virtual bool flush(); virtual qint64 size() const; virtual qint64 pos() const; + virtual bool setSize(qint64 size); virtual bool seek(qint64 pos); virtual bool isSequential() const; virtual bool remove(); @@ -55,6 +56,7 @@ QString m_fileName; QDateTime m_date; bool m_bufferSet; + bool m_readWrite; }; class FileEngineHandler : public QAbstractFileEngineHandler diff -r f781204831ab -r 555a6e06cb33 cmake_modules/FindFreepascal.cmake --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cmake_modules/FindFreepascal.cmake Tue Dec 04 01:52:14 2012 +0100 @@ -0,0 +1,36 @@ +# Load Freepascal +if (FPC) + set(FPC_EXECUTABLE ${FPC}) +else() + find_program(FPC_EXECUTABLE + NAMES fpc + PATHS /opt/local/bin /usr/local/bin /usr/bin) +endif() + +# Check Freepascal version +if (FPC_EXECUTABLE) + exec_program(${FPC_EXECUTABLE} ARGS "-v" OUTPUT_VARIABLE FPC_VERSION_FULL) + + string(REGEX MATCH "[0-9]+\\.[0-9]+" FPC_VERSION_LONG "${FPC_VERSION_FULL}") + string(REGEX REPLACE "([0-9]+\\.[0-9]+)" "\\1" FPC_VERSION "${FPC_VERSION_LONG}") + message(STATUS "Found Freepascal: ${FPC_EXECUTABLE} (version ${FPC_VERSION}") +else() + message(FATAL_ERROR "Could NOT find Freepascal") +endif() + +# Check for noexecstack flag support +set(NOEXECSTACK_FLAGS "-k-z" "-knoexecstack") +file(WRITE ${EXECUTABLE_OUTPUT_PATH}/checkstack.pas "begin end.") + +execute_process(COMMAND ${FPC_EXECUTABLE} ${NOEXECSTACK_FLAGS} checkstack.pas + WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} + RESULT_VARIABLE TEST_NOEXECSTACK + OUTPUT_QUIET ERROR_QUIET) + +if (TEST_NOEXECSTACK) + set(NOEXECSTACK_FLAGS "") + message(STATUS "Checking whether linker needs explicit noexecstack -- no") +else(TEST_NOEXECSTACK) + message(STATUS "Checking whether linker needs explicit noexecstack -- yes") +endif(TEST_NOEXECSTACK) + diff -r f781204831ab -r 555a6e06cb33 gameServer/Actions.hs --- a/gameServer/Actions.hs Fri Nov 30 23:04:49 2012 -0500 +++ b/gameServer/Actions.hs Tue Dec 04 01:52:14 2012 +0100 @@ -441,17 +441,25 @@ return () -processAction (ProcessAccountInfo info) = +processAction (ProcessAccountInfo info) = do case info of HasAccount passwd isAdmin -> do - chan <- client's sendChan - mapM_ processAction [AnswerClients [chan] ["ASKPASSWORD"], ModifyClient (\c -> c{webPassword = passwd, isAdministrator = isAdmin})] - Guest -> - processAction JoinLobby + b <- isBanned + when (not b) $ do + chan <- client's sendChan + mapM_ processAction [AnswerClients [chan] ["ASKPASSWORD"], ModifyClient (\c -> c{webPassword = passwd, isAdministrator = isAdmin})] + Guest -> do + b <- isBanned + when (not b) $ + processAction JoinLobby Admin -> do mapM_ processAction [ModifyClient (\cl -> cl{isAdministrator = True}), JoinLobby] chan <- client's sendChan processAction $ AnswerClients [chan] ["ADMIN_ACCESS"] + where + isBanned = do + processAction CheckBanned + liftM B.null $ client's nick processAction JoinLobby = do diff -r f781204831ab -r 555a6e06cb33 gameServer/HWProtoInRoomState.hs --- a/gameServer/HWProtoInRoomState.hs Fri Nov 30 23:04:49 2012 -0500 +++ b/gameServer/HWProtoInRoomState.hs Tue Dec 04 01:52:14 2012 +0100 @@ -308,8 +308,8 @@ let sameRoom = clientRoom rnc thisClientId == clientRoom rnc banId if master && isJust maybeClientId && (banId /= thisClientId) && sameRoom then return [ - ModifyRoom (\r -> r{roomBansList = let h = host $ rnc `client` banId in h `deepseq` h : roomBansList r}) - , KickRoomClient banId +-- ModifyRoom (\r -> r{roomBansList = let h = host $ rnc `client` banId in h `deepseq` h : roomBansList r}) + KickRoomClient banId ] else return [] diff -r f781204831ab -r 555a6e06cb33 hedgewars/ArgParsers.inc --- a/hedgewars/ArgParsers.inc Fri Nov 30 23:04:49 2012 -0500 +++ b/hedgewars/ArgParsers.inc Tue Dec 04 01:52:14 2012 +0100 @@ -122,52 +122,60 @@ const otherArray: Array [1..3] of String = ('--locale','--fullscreen','--showfps'); const mediaArray: Array [1..8] of String = ('--width','--height','--depth','--volume','--nomusic','--nosound','--locale','--fullscreen'); const allArray: Array [1..12] of String = ('--width','--height','--depth','--volume','--nomusic','--nosound','--locale','--fullscreen','--showfps','--altdmg','--time','--lowquality'); +const reallyAll: array[0..19] of shortstring = ( + '--locale', '--width', '--height', '--depth', '--time' + , '--volume', '--nomusic', '--nosound', '--fullscreen', '--showfps' + , '--altdmg', '--lowquality', '--set-video', '--set-audio', '--set-other' + , '--set-multimedia', '--set-everything', '--stats-only', '--gci', '--help'); +var cmdIndex: byte; begin parseParameter:= false; - case cmd of - '--locale' : cLocaleFName := getStringParameter (arg, paramIndex); - '--width' : cScreenWidth := getLongIntParameter(arg, paramIndex, parseParameter); - '--height' : cScreenHeight := getLongIntParameter(arg, paramIndex, parseParameter); - '--depth' : cBits := getLongIntParameter(arg, paramIndex, parseParameter); - '--time' : cTimerInterval := getLongIntParameter(arg, paramIndex, parseParameter); - '--volume' : SetVolume ( getLongIntParameter(arg, paramIndex, parseParameter) ); - '--nomusic' : SetMusic ( false ); - '--nosound' : SetSound ( false ); - '--fullscreen' : cFullScreen := true; - '--showfps' : cShowFPS := true; - '--altdmg' : cAltDamage := true; - '--lowquality' : cReducedQuality:= ($FFFFFFFF * getLongIntParameter(arg, paramIndex, parseParameter)) xor rqLowRes; //HACK! - '--set-video' : parseClassicParameter(videoArray,3,paramIndex); - '--set-audio' : parseClassicParameter(audioArray,3,paramIndex); - '--set-other' : parseClassicParameter(otherArray,3,paramIndex); - '--set-multimedia' : parseClassicParameter(mediaArray,8,paramIndex); - '--set-everything' : parseClassicParameter(allArray,12,paramIndex); - '--stats-only' : begin - cOnlyStats:= true; - SetSound(false); - SetMusic(false); - cReducedQuality:= $FFFFFFFF xor rqLowRes; - end; - '--gci' : begin // We had to make up all this saved space some how... \\ - WriteLn(stdout, ' '); - WriteLn(stdout, ' /\\\\\\\\\\\\ /\\\\\\\\\ /\\\\\\\\\\\ '); - WriteLn(stdout, ' /\\\////////// /\\\//////// \/////\\\/// '); - WriteLn(stdout, ' /\\\ /\\\/ \/\\\ '); - WriteLn(stdout, ' \/\\\ /\\\\\\\ /\\\ \/\\\ '); - WriteLn(stdout, ' \/\\\ \/////\\\ \/\\\ \/\\\ '); - WriteLn(stdout, ' \/\\\ \/\\\ \//\\\ \/\\\ '); - WriteLn(stdout, ' \/\\\ \/\\\ \///\\\ \/\\\ '); - WriteLn(stdout, ' \//\\\\\\\\\\\\/ \////\\\\\\\\\ /\\\\\\\\\\\ '); - WriteLn(stdout, ' \//////////// \///////// \/////////// '); - WriteLn(stdout, ' '); - WriteLn(stdout, ' Command Line Parser Implementation by a Google Code-In Student '); - WriteLn(stdout, ' ASCII Art easter egg idea by @sheepluva '); - WriteLn(stdout, ' '); - end; - '--help' : begin - DisplayUsage(); - GameType:= gmtSyntax; - end; + cmdIndex:= 0; + while (cmdIndex <= High(reallyAll)) and (cmd <> reallyAll[cmdIndex]) do inc(cmdIndex); + case cmdIndex of + {--locale} 0 : cLocaleFName := getStringParameter (arg, paramIndex); + {--width} 1 : cScreenWidth := getLongIntParameter(arg, paramIndex, parseParameter); + {--height} 2 : cScreenHeight := getLongIntParameter(arg, paramIndex, parseParameter); + {--depth} 3 : cBits := getLongIntParameter(arg, paramIndex, parseParameter); + {--time} 4 : cTimerInterval := getLongIntParameter(arg, paramIndex, parseParameter); + {--volume} 5 : SetVolume ( getLongIntParameter(arg, paramIndex, parseParameter) ); + {--nomusic} 6 : SetMusic ( false ); + {--nosound} 7 : SetSound ( false ); + {--fullscreen} 8 : cFullScreen := true; + {--showfps} 9 : cShowFPS := true; + {--altdmg} 10 : cAltDamage := true; + {--lowquality} 11 : cReducedQuality:= ($FFFFFFFF * getLongIntParameter(arg, paramIndex, parseParameter)) xor rqLowRes; //HACK! + {--set-video} 12 : parseClassicParameter(videoArray,3,paramIndex); + {--set-audio} 13 : parseClassicParameter(audioArray,3,paramIndex); + {--set-other} 14 : parseClassicParameter(otherArray,3,paramIndex); + {--set-multimedia} 15 : parseClassicParameter(mediaArray,8,paramIndex); + {--set-everything} 16 : parseClassicParameter(allArray,12,paramIndex); + {--stats-only} 17 : begin + cOnlyStats:= true; + SetSound(false); + SetMusic(false); + cReducedQuality:= $FFFFFFFF xor rqLowRes; + end; + {--gci} 18 : begin // We had to make up all this saved space some how... \\ + WriteLn(stdout, ' '); + WriteLn(stdout, ' /\\\\\\\\\\\\ /\\\\\\\\\ /\\\\\\\\\\\ '); + WriteLn(stdout, ' /\\\////////// /\\\//////// \/////\\\/// '); + WriteLn(stdout, ' /\\\ /\\\/ \/\\\ '); + WriteLn(stdout, ' \/\\\ /\\\\\\\ /\\\ \/\\\ '); + WriteLn(stdout, ' \/\\\ \/////\\\ \/\\\ \/\\\ '); + WriteLn(stdout, ' \/\\\ \/\\\ \//\\\ \/\\\ '); + WriteLn(stdout, ' \/\\\ \/\\\ \///\\\ \/\\\ '); + WriteLn(stdout, ' \//\\\\\\\\\\\\/ \////\\\\\\\\\ /\\\\\\\\\\\ '); + WriteLn(stdout, ' \//////////// \///////// \/////////// '); + WriteLn(stdout, ' '); + WriteLn(stdout, ' Command Line Parser Implementation by a Google Code-In Student '); + WriteLn(stdout, ' ASCII Art easter egg idea by @sheepluva '); + WriteLn(stdout, ' '); + end; + {--help} 19 : begin + DisplayUsage(); + GameType:= gmtSyntax; + end; else begin WriteLn(stderr, 'ERROR: '+cmd+' is not a valid argument'); @@ -185,20 +193,23 @@ while (index < size) do begin paramIndex:= paramIndex+1; - //This next line is a really strange (but short), way to check if the parameter is a boolean one - isBool:= true; case cmdArray[index] of '--nomusic':;'--nosound':;'--fullscreen':;'--showfps':;'--altdmg':;'--lowquality':; else isBool:= false; end; + // check if the parameter is a boolean one + isBool:= (cmdArray[index] = '--nomusic') + or (cmdArray[index] = '--nosound') + or (cmdArray[index] = '--fullscreen') + or (cmdArray[index] = '--showfps') + or (cmdArray[index] = '--altdmg') + or (cmdArray[index] = '--lowquality'); if (not isBool) or ((ParamStr(paramIndex)='1') and (cmdArray[index]<>'--nomusic') and (cmdArray[index]<>'--nosound')) then parseParameter(cmdArray[index], ParamStr(paramIndex), tmpInt); - //if isBool then - // paramIndex:= paramIndex+1; index:= index+1; end; end; procedure playReplayFileWithParameters(paramIndex: LongInt); -var wrongParameter: boolean; +var tmpInt: LongInt; + wrongParameter: boolean; begin - paramIndex:= 4; wrongParameter:= false; while (paramIndex <= ParamCount) do begin diff -r f781204831ab -r 555a6e06cb33 hedgewars/CMakeLists.txt --- a/hedgewars/CMakeLists.txt Fri Nov 30 23:04:49 2012 -0500 +++ b/hedgewars/CMakeLists.txt Tue Dec 04 01:52:14 2012 +0100 @@ -12,6 +12,12 @@ set(hwengine_project ${hedgewars_SOURCE_DIR}/hedgewars/hwengine.pas) set(engine_output_name "hwengine") +if (APPLE) + set(required_fpc_version 2.6) +else() + set(required_fpc_version 2.2) +endif() + set(engine_sources ${hwengine_project} LuaPas.pas @@ -53,7 +59,6 @@ uLandTexture.pas uLocale.pas uMisc.pas - uMobile.pas uPhysFSLayer.pas uRandom.pas uRender.pas @@ -101,54 +106,13 @@ endif(BUILD_ENGINE_LIBRARY) -#PASCAL DETECTION SECTION -if(FPC) - set(fpc_executable ${FPC}) -else() - find_program(fpc_executable fpc) +# Check Freepascal version +find_package(Freepascal) + +if (FPC_VERSION VERSION_LESS required_fpc_version) + message(FATAL_ERROR "Freepascal is too old, minimum version required is ${required_fpc_version}") endif() -message(STATUS "Check for working FPC compiler: ${fpc_executable}") -execute_process(COMMAND ${fpc_executable} -iV OUTPUT_VARIABLE fpc_output ERROR_VARIABLE fpc_error) -if(fpc_error) - message(STATUS "Check for working FPC compiler: ${fpc_executable} -- broken") -else(fpc_error) - message(STATUS "Check for working FPC compiler: ${fpc_executable} -- works") -endif(fpc_error) - -string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" fpc_version "${fpc_output}") -if(fpc_version) - string(REGEX REPLACE "([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" fpc_vers_major "${fpc_version}") - string(REGEX REPLACE "[0-9]+\\.([0-9]+)\\.[0-9]+" "\\1" fpc_vers_minor "${fpc_version}") - string(REGEX REPLACE "[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" fpc_vers_patch "${fpc_version}") - message(STATUS "Found Freepascal: ${fpc_executable} (version ${fpc_vers_major}.${fpc_vers_minor})") - math(EXPR fpc_version "${fpc_vers_major}*10000 + ${fpc_vers_minor}*100 + ${fpc_vers_patch}") - - if(fpc_version LESS "020200") - message(FATAL_ERROR "Minimum required version of FreePascal is 2.2.0") - elseif(APPLE AND (fpc_version LESS "020600")) - message(FATAL_ERROR "Minimum required version of FreePascal is 2.6.0 on Mac OS X") - endif() -else() - message(FATAL_ERROR "No FreePascal compiler found!") -endif() - -message(STATUS "Checking whether linker supports noexecstack flag") -set(noexecstack_flags "-k-z" "-knoexecstack") -file(WRITE ${EXECUTABLE_OUTPUT_PATH}/checkstack.pas "begin end.") - -execute_process(COMMAND ${fpc_executable} ${noexecstack_flags} checkstack.pas - WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} - RESULT_VARIABLE testnoexecstack - OUTPUT_QUIET ERROR_QUIET - ) - -if(${testnoexecstack}) - set (noexecstack_flags "") - message(STATUS "Checking whether linker supports noexecstack flag -- no") -else(${testnoexecstack}) - message(STATUS "Checking whether linker supports noexecstack flag -- yes") -endif(${testnoexecstack}) #DEPENDECIES AND EXECUTABLES SECTION if(APPLE) @@ -198,9 +162,8 @@ #this command is a workaround to some inlining issues present in older FreePascal versions and fixed in 2.6 -if(fpc_version LESS "020600") +if(FPC_VERSION VERSION_LESS "2.6") #under some configurations CMAKE_BUILD_TOOL fails to pass on the jobserver, breaking parallel compilation - #TODO: check if this is needed on windows too if(UNIX) set(SAFE_BUILD_TOOL $(MAKE)) else() @@ -239,12 +202,12 @@ set(pascal_flags "-Fl${LIBRARY_OUTPUT_PATH}" ${pascal_flags}) -set(fpc_flags ${noexecstack_flags} ${pascal_flags} ${hwengine_project}) +set(fpc_flags ${NOEXECSTACK_FLAGS} ${pascal_flags} ${hwengine_project}) if(NOT APPLE) #here is the command for standard executables or for shared library add_custom_command(OUTPUT "${EXECUTABLE_OUTPUT_PATH}/${engine_output_name}${CMAKE_EXECUTABLE_SUFFIX}" - COMMAND "${fpc_executable}" + COMMAND "${FPC_EXECUTABLE}" ARGS ${fpc_flags} MAIN_DEPENDENCY ${hwengine_project} DEPENDS ${engine_sources} @@ -254,7 +217,7 @@ foreach (build_arch ${powerpc_build} ${i386_build} ${x86_64_build}) set(lipo_args_list "${EXECUTABLE_OUTPUT_PATH}/hwengine.${build_arch}" ${lipo_args_list}) add_custom_command(OUTPUT "${EXECUTABLE_OUTPUT_PATH}/hwengine.${build_arch}" - COMMAND "${fpc_executable}" + COMMAND "${FPC_EXECUTABLE}" ARGS ${fpc_flags} -ohwengine.${build_arch} -P${build_arch} MAIN_DEPENDENCY ${hwengine_project} DEPENDS ${engine_sources} @@ -287,7 +250,7 @@ endif() #this command is a workaround to some inlining issues present in older FreePascal versions and fixed in 2.6 -if((fpc_version LESS "020600") AND (NOVIDEOREC OR NOT ${FFMPEG_FOUND})) +if((FPC_VERSION VERSION_LESS "2.6") AND (NOVIDEOREC OR NOT ${FFMPEG_FOUND})) add_dependencies(${engine_output_name} ENGINECLEAN) endif() diff -r f781204831ab -r 555a6e06cb33 hedgewars/GSHandlers.inc --- a/hedgewars/GSHandlers.inc Fri Nov 30 23:04:49 2012 -0500 +++ b/hedgewars/GSHandlers.inc Tue Dec 04 01:52:14 2012 +0100 @@ -2223,7 +2223,9 @@ begin doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound); DeleteGear(Gear); - performRumble(); + with mobileRecord do + if (performRumble <> nil) and (not fastUntilLag) then + performRumble(kSystemSoundID_Vibrate); exit end; if (GameTicks and $3F) = 0 then @@ -4308,7 +4310,9 @@ Gear^.dY.isNegative := not Gear^.dY.isNegative; Gear^.doStep := @doStepSineGunShotWork; - performRumble(); + with mobileRecord do + if (performRumble <> nil) and (not fastUntilLag) then + performRumble(kSystemSoundID_Vibrate); end; //////////////////////////////////////////////////////////////////////////////// diff -r f781204831ab -r 555a6e06cb33 hedgewars/VGSHandlers.inc --- a/hedgewars/VGSHandlers.inc Fri Nov 30 23:04:49 2012 -0500 +++ b/hedgewars/VGSHandlers.inc Tue Dec 04 01:52:14 2012 +0100 @@ -697,7 +697,9 @@ Gear^.doStep:= @doStepBigExplosionWork; if Steps > 1 then Gear^.doStep(Gear, Steps-1); -performRumble(); +with mobileRecord do + if (performRumble <> nil) and (not fastUntilLag) then + performRumble(kSystemSoundID_Vibrate); end; procedure doStepChunk(Gear: PVisualGear; Steps: Longword); diff -r f781204831ab -r 555a6e06cb33 hedgewars/hwengine.pas --- a/hedgewars/hwengine.pas Fri Nov 30 23:04:49 2012 -0500 +++ b/hedgewars/hwengine.pas Tue Dec 04 01:52:14 2012 +0100 @@ -541,25 +541,30 @@ {$INCLUDE "ArgParsers.inc"} procedure GetParams; -var tmpInt: LongInt; +var startIndex,tmpInt: LongInt; + debug: string; begin if (ParamCount < 2) then - GameType:= gmtSyntax + begin + DisplayUsage(); + GameType:= gmtSyntax; + end else + begin if (ParamCount >= 2) then begin - UserPathPrefix:= ParamStr(1); - PathPrefix:= ParamStr(2) + UserPathPrefix := ParamStr(1); + PathPrefix := ParamStr(2) end; if (ParamCount >= 3) then - recordFileName:= ParamStr(3); + recordFilename := ParamStr(3); if (ParamCount = 2) or ((ParamCount >= 3) and (Copy(recordFileName,1,2) = '--')) then begin recordFileName := PathPrefix; - PathPrefix := UserPathPrefix; + PathPrefix := UserPathPrefix; + UserPathPrefix := '.'; startIndex := 3; - WriteLn(stdout,'defaulting UserPathPrefix') end else startIndex := 4; @@ -584,6 +589,10 @@ else playReplayFileWithParameters(startIndex); end + end; + WriteLn(stdout,recordFilename); + WriteLn(stdout,PathPrefix); + WriteLn(stdout,UserPathPrefix); end; /////////////////////////////////////////////////////////////////////////////// diff -r f781204831ab -r 555a6e06cb33 hedgewars/uConsts.pas --- a/hedgewars/uConsts.pas Fri Nov 30 23:04:49 2012 -0500 +++ b/hedgewars/uConsts.pas Tue Dec 04 01:52:14 2012 +0100 @@ -275,6 +275,8 @@ NoPointX = Low(LongInt); cTargetPointRef : TPoint = (X: NoPointX; Y: 0); + kSystemSoundID_Vibrate = $00000FFF; + implementation end. diff -r f781204831ab -r 555a6e06cb33 hedgewars/uGame.pas --- a/hedgewars/uGame.pas Fri Nov 30 23:04:49 2012 -0500 +++ b/hedgewars/uGame.pas Tue Dec 04 01:52:14 2012 +0100 @@ -26,7 +26,7 @@ //////////////////// implementation //////////////////// -uses uInputHandler, uTeams, uIO, uAI, uGears, uSound, uMobile, +uses uInputHandler, uTeams, uIO, uAI, uGears, uSound, uVisualGears, uTypes, uVariables, uCommands, uConsts {$IFDEF USE_TOUCH_INTERFACE}, uTouch{$ENDIF}; @@ -96,7 +96,9 @@ AddVisualGear(0, 0, vgtTeamHealthSorter); AddVisualGear(0, 0, vgtSmoothWindBar); {$IFDEF IPHONEOS}InitIPC;{$ENDIF} - uMobile.SaveLoadingEnded(); + with mobileRecord do + if SaveLoadingEnded <> nil then + SaveLoadingEnded(); end; end else ProcessGears diff -r f781204831ab -r 555a6e06cb33 hedgewars/uGears.pas --- a/hedgewars/uGears.pas Fri Nov 30 23:04:49 2012 -0500 +++ b/hedgewars/uGears.pas Tue Dec 04 01:52:14 2012 +0100 @@ -57,7 +57,7 @@ implementation uses uStore, uSound, uTeams, uRandom, uCollisions, uIO, uLandGraphics, - uLocale, uAI, uAmmos, uStats, uVisualGears, uScript, GLunit, uMobile, uVariables, + uLocale, uAI, uAmmos, uStats, uVisualGears, uScript, GLunit, uVariables, uCommands, uUtils, uTextures, uRenderUtils, uGearsRender, uCaptions, uDebug, uLandTexture, uGearsHedgehog, uGearsUtils, uGearsList, uGearsHandlers, uGearsHandlersRope; diff -r f781204831ab -r 555a6e06cb33 hedgewars/uGearsUtils.pas --- a/hedgewars/uGearsUtils.pas Fri Nov 30 23:04:49 2012 -0500 +++ b/hedgewars/uGearsUtils.pas Tue Dec 04 01:52:14 2012 +0100 @@ -243,7 +243,7 @@ end; uStats.HedgehogDamaged(Gear, AttackerHog, Damage, false); end; - end; + end else //else if Gear^.Kind <> gtStructure then // not gtHedgehog nor gtStructure Gear^.Hedgehog:= AttackerHog; inc(Gear^.Damage, Damage); diff -r f781204831ab -r 555a6e06cb33 hedgewars/uLand.pas --- a/hedgewars/uLand.pas Fri Nov 30 23:04:49 2012 -0500 +++ b/hedgewars/uLand.pas Tue Dec 04 01:52:14 2012 +0100 @@ -596,7 +596,7 @@ begin map:= cPathz[ptMapCurrent] + '/map.png'; mask:= cPathz[ptMapCurrent] + '/mask.png'; - if (not(FileExists(map)) and FileExists(mask)) then + if (not(pfsExists(map)) and pfsExists(mask)) then begin maskOnly:= true; LoadMask; diff -r f781204831ab -r 555a6e06cb33 hedgewars/uMobile.pas --- a/hedgewars/uMobile.pas Fri Nov 30 23:04:49 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -(* - * Hedgewars, a free turn based strategy game - * Copyright (c) 2004-2012 Andrey Korotaev - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - *) - -{$INCLUDE "options.inc"} - -(* - * This unit contains a lot of useful functions when hw is running on mobile - * Unlike HwLibrary when you declare functions that you will call from your code, - * here you need to provide functions that Pascall code will call. - *) - -unit uMobile; -interface - -function isPhone: Boolean; inline; -function getScreenDPI: Double; inline; -procedure performRumble; inline; - -procedure GameLoading; inline; -procedure GameLoaded; inline; -procedure SaveLoadingEnded; inline; - -implementation -uses uVariables, uConsole, SDLh; - -// add here any external call that you need -{$IFDEF IPHONEOS} -(* iOS calls written in ObjcExports.m *) -procedure startLoadingIndicator; cdecl; external; -procedure stopLoadingIndicator; cdecl; external; -procedure saveFinishedSynching; cdecl; external; -function isApplePhone: Boolean; cdecl; external; -procedure AudioServicesPlaySystemSound(num: LongInt); cdecl; external; -{$ENDIF} - -// this function is just to determine whether we are running on a limited screen device -function isPhone: Boolean; inline; -begin - isPhone:= false; -{$IFDEF IPHONEOS} - isPhone:= isApplePhone(); -{$ENDIF} -{$IFDEF ANDROID} - //nasty nasty hack. TODO: implement callback to java to have a unified way of determining if it is a tablet - if (cScreenWidth < 1000) and (cScreenHeight < 500) then - isPhone:= true; -{$ENDIF} -end; - -function getScreenDPI: Double; inline; -begin -{$IFDEF ANDROID} -// getScreenDPI:= Android_JNI_getDensity(); - getScreenDPI:= 1; -{$ELSE} - getScreenDPI:= 1; -{$ENDIF} -end; - -// this function should make the device vibrate in some way -procedure PerformRumble; inline; -{$IFDEF IPHONEOS}const kSystemSoundID_Vibrate = $00000FFF;{$ENDIF} -begin - // do not vibrate while synchronising a demo/save - if not fastUntilLag then - begin -{$IFDEF IPHONEOS} - AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); -{$ENDIF} - end; -end; - -procedure GameLoading; inline; -begin -{$IFDEF IPHONEOS} - startLoadingIndicator(); -{$ENDIF} -end; - -procedure GameLoaded; inline; -begin -{$IFDEF IPHONEOS} - stopLoadingIndicator(); -{$ENDIF} -end; - -procedure SaveLoadingEnded; inline; -begin -{$IFDEF IPHONEOS} - saveFinishedSynching(); -{$ENDIF} -end; - - -end. diff -r f781204831ab -r 555a6e06cb33 hedgewars/uSound.pas --- a/hedgewars/uSound.pas Fri Nov 30 23:04:49 2012 -0500 +++ b/hedgewars/uSound.pas Tue Dec 04 01:52:14 2012 +0100 @@ -386,7 +386,7 @@ if (voicepack^.chunks[snd] = nil) and (Soundz[snd].Path = ptVoices) and (Soundz[snd].FileName <> '') then begin s:= cPathz[Soundz[snd].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName; - if (not FileExists(s)) and (snd in [sndFirePunch2, sndFirePunch3, sndFirePunch4, sndFirePunch5, sndFirePunch6]) then + if (not pfsExists(s)) and (snd in [sndFirePunch2, sndFirePunch3, sndFirePunch4, sndFirePunch5, sndFirePunch6]) then s:= cPathz[Soundz[sndFirePunch1].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName; WriteToConsole(msgLoading + s + ' '); voicepack^.chunks[snd]:= Mix_LoadWAV_RW(rwopsOpenRead(s), 1); diff -r f781204831ab -r 555a6e06cb33 hedgewars/uStore.pas --- a/hedgewars/uStore.pas Fri Nov 30 23:04:49 2012 -0500 +++ b/hedgewars/uStore.pas Tue Dec 04 01:52:14 2012 +0100 @@ -56,7 +56,7 @@ procedure SwapBuffers; {$IFDEF USE_VIDEO_RECORDING}cdecl{$ELSE}inline{$ENDIF}; implementation -uses uMisc, uConsole, uMobile, uVariables, uUtils, uTextures, uRender, uRenderUtils, uCommands +uses uMisc, uConsole, uVariables, uUtils, uTextures, uRender, uRenderUtils, uCommands , uPhysFSLayer , uDebug {$IFDEF USE_CONTEXT_RESTORE}, uWorld{$ENDIF} @@ -886,8 +886,10 @@ squaresize:= texsurf^.w shr 1; numsquares:= texsurf^.h div squaresize; SDL_FreeSurface(texsurf); - - uMobile.GameLoading(); + with mobileRecord do + if GameLoading <> nil then + GameLoading(); + end; TryDo(ProgrTex <> nil, 'Error - Progress Texure is nil!', true); @@ -910,7 +912,9 @@ procedure FinishProgress; begin - uMobile.GameLoaded(); + with mobileRecord do + if GameLoaded <> nil then + GameLoaded(); WriteLnToConsole('Freeing progress surface... '); FreeTexture(ProgrTex); ProgrTex:= nil; diff -r f781204831ab -r 555a6e06cb33 hedgewars/uTouch.pas --- a/hedgewars/uTouch.pas Fri Nov 30 23:04:49 2012 -0500 +++ b/hedgewars/uTouch.pas Tue Dec 04 01:52:14 2012 +0100 @@ -22,7 +22,7 @@ interface -uses SysUtils, uConsole, uVariables, SDLh, uFloat, uConsts, uCommands, GLUnit, uTypes, uCaptions, uAmmos, uWorld, uMobile; +uses SysUtils, uConsole, uVariables, SDLh, uFloat, uConsts, uCommands, GLUnit, uTypes, uCaptions, uAmmos, uWorld; procedure initModule; @@ -558,7 +558,7 @@ isOnCrosshair:= isOnRect((x-HalfRectSize), (y-HalfRectSize), RectSize, RectSize, finger); printFinger(finger); WriteLnToConsole(inttostr(finger.x) + ' ' + inttostr(x)); - WriteLnToConsole(inttostr(x) + ' ' + inttostr(y) + ' ' + inttostr(round(uMobile.getScreenDPI * 10))); + WriteLnToConsole(inttostr(x) + ' ' + inttostr(y) + ' ' + inttostr(round(mobileRecord.getScreenDPI() * 10))); end; function isOnCurrentHog(finger: TTouch_Data): boolean; @@ -640,7 +640,7 @@ for index := 0 to High(fingers) do fingers[index].id := nilFingerId; - rectSize:= round(baseRectSize * uMobile.getScreenDPI); + rectSize:= round(baseRectSize * mobileRecord.getScreenDPI()); halfRectSize:= rectSize shl 1; end; diff -r f781204831ab -r 555a6e06cb33 hedgewars/uTypes.pas --- a/hedgewars/uTypes.pas Fri Nov 30 23:04:49 2012 -0500 +++ b/hedgewars/uTypes.pas Tue Dec 04 01:52:14 2012 +0100 @@ -399,6 +399,18 @@ Flawless: boolean; end; + cdeclPtr = procedure; cdecl; + cdeclIntPtr = procedure(num: LongInt); cdecl; + functionDoublePtr = function: Double; + + TMobileRecord = record + getScreenDPI: functionDoublePtr; + PerformRumble: cdeclIntPtr; + GameLoading: cdeclPtr; + GameLoaded: cdeclPtr; + SaveLoadingEnded: cdeclPtr; + end; + TAmmoStrId = (sidGrenade, sidClusterBomb, sidBazooka, sidBee, sidShotgun, sidPickHammer, sidSkip, sidRope, sidMine, sidDEagle, sidDynamite, sidBaseballBat, sidFirePunch, sidSeconds, diff -r f781204831ab -r 555a6e06cb33 hedgewars/uUtils.pas --- a/hedgewars/uUtils.pas Fri Nov 30 23:04:49 2012 -0500 +++ b/hedgewars/uUtils.pas Tue Dec 04 01:52:14 2012 +0100 @@ -73,6 +73,17 @@ procedure WriteLn(var f: textfile; s: shortstring); {$ENDIF} +function isPhone: Boolean; inline; +function getScreenDPI: Double; inline; //cdecl; external; + +{$IFDEF IPHONEOS} +procedure startLoadingIndicator; cdecl; external; +procedure stopLoadingIndicator; cdecl; external; +procedure saveFinishedSynching; cdecl; external; +function isApplePhone: Boolean; cdecl; external; +procedure AudioServicesPlaySystemSound(num: LongInt); cdecl; external; +{$ENDIF} + procedure initModule(isNotPreview: boolean); procedure freeModule; @@ -401,6 +412,31 @@ end; {$ENDIF} +// this function is just to determine whether we are running on a limited screen device +function isPhone: Boolean; inline; +begin + isPhone:= false; +{$IFDEF IPHONEOS} + isPhone:= isApplePhone(); +{$ENDIF} +{$IFDEF ANDROID} + //nasty nasty hack. TODO: implement callback to java to have a unified way of determining if it is a tablet + if (cScreenWidth < 1000) and (cScreenHeight < 500) then + isPhone:= true; +{$ENDIF} +end; + +//This dummy function should be reimplemented (externally). +function getScreenDPI: Double; inline; +begin +{$IFDEF ANDROID} +// getScreenDPI:= Android_JNI_getDensity(); + getScreenDPI:= 1; +{$ELSE} + getScreenDPI:= 1; +{$ENDIF} +end; + procedure initModule(isNotPreview: boolean); {$IFDEF DEBUGFILE} var logfileBase: shortstring; diff -r f781204831ab -r 555a6e06cb33 hedgewars/uVariables.pas --- a/hedgewars/uVariables.pas Fri Nov 30 23:04:49 2012 -0500 +++ b/hedgewars/uVariables.pas Tue Dec 04 01:52:14 2012 +0100 @@ -21,7 +21,7 @@ unit uVariables; interface -uses SDLh, uTypes, uFloat, GLunit, uConsts, Math, uMobile, uUtils; +uses SDLh, uTypes, uFloat, GLunit, uConsts, Math, uUtils; var /////// init flags /////// @@ -197,6 +197,8 @@ LastVoice : TVoice = ( snd: sndNone; voicepack: nil ); + mobileRecord: TMobileRecord; + ///////////////////////////////////// //Buttons {$IFDEF USE_TOUCH_INTERFACE} @@ -2519,6 +2521,19 @@ cMapName:= ''; LuaTemplateNumber:= 0; + + mobileRecord.getScreenDPI:= @getScreenDPI; //TODO: define external function. + {$IFDEF IPHONEOS} + mobileRecord.PerformRumble:= @AudioServicesPlaySystemSound; + mobileRecord.GameLoading:= @startLoadingIndicator; + mobileRecord.GameLoaded:= @stopLoadingIndicator; + mobileRecord.SaveLoadingEnded:= @saveFinishedSynching; + {$ELSE} + mobileRecord.PerformRumble:= nil; + mobileRecord.GameLoading:= nil; + mobileRecord.GameLoaded:= nil; + mobileRecord.SaveLoadingEnded:= nil; + {$ENDIF} end; procedure freeModule; diff -r f781204831ab -r 555a6e06cb33 hedgewars/uVisualGears.pas --- a/hedgewars/uVisualGears.pas Fri Nov 30 23:04:49 2012 -0500 +++ b/hedgewars/uVisualGears.pas Tue Dec 04 01:52:14 2012 +0100 @@ -53,7 +53,7 @@ procedure KickFlakes(Radius, X, Y: LongInt); implementation -uses uSound, uMobile, uVariables, uTextures, uRender, Math, uRenderUtils, uStore, uUtils; +uses uSound, uVariables, uTextures, uRender, Math, uRenderUtils, uStore, uUtils; const cExplFrameTicks = 110; diff -r f781204831ab -r 555a6e06cb33 hedgewars/uWorld.pas --- a/hedgewars/uWorld.pas Fri Nov 30 23:04:49 2012 -0500 +++ b/hedgewars/uWorld.pas Tue Dec 04 01:52:14 2012 +0100 @@ -60,7 +60,6 @@ , uCaptions , uCursor , uCommands - , uMobile {$IFDEF USE_VIDEO_RECORDING} , uVideoRec {$ENDIF} @@ -246,7 +245,7 @@ {$IFDEF USE_TOUCH_INTERFACE} //positioning of the buttons -buttonScale:= uMobile.getScreenDPI/cDefaultZoomLevel; +buttonScale:= mobileRecord.getScreenDPI()/cDefaultZoomLevel; with JumpWidget do diff -r f781204831ab -r 555a6e06cb33 share/hedgewars/Data/Graphics/AmmoMenu/BorderHorizontal.png Binary file share/hedgewars/Data/Graphics/AmmoMenu/BorderHorizontal.png has changed diff -r f781204831ab -r 555a6e06cb33 share/hedgewars/Data/Graphics/AmmoMenu/BorderVertical.png Binary file share/hedgewars/Data/Graphics/AmmoMenu/BorderVertical.png has changed