second merge
authorkoda
Tue, 04 Dec 2012 01:52:14 +0100
changeset 8211 555a6e06cb33
parent 8209 780e156f19ea (diff)
parent 8171 f781204831ab (current diff)
child 8213 81553c5b9fd0
second merge
--- 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}
--- 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();
 }
--- 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();
--- 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);
 }
 
--- 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<HWGame> game;
         QPointer<HWNetServer> pnetserver;
--- 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;
--- 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);
--- 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()));
--- 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;
 };
 
--- 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);
 
--- 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())
     {
--- 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!"));
     }
 
 }
--- 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);
 }
--- 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;
 };
--- 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 <QStandardItemModel>
 
 #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;
+}
--- 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<QPushButton *> 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
--- 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()
--- 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;
--- 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)
 {
--- 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);
--- 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)
 {
--- 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);
--- 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();
--- 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
--- 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;
 }
--- 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
--- /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)
+
--- 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
--- 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 []
--- 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
--- 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()
 
--- 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;
 
 ////////////////////////////////////////////////////////////////////////////////
--- 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);
--- 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;
 
 ///////////////////////////////////////////////////////////////////////////////
--- 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.
--- 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
--- 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;
 
--- 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);
--- 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;
--- 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 <unC0Rr@gmail.com>
- *
- * 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.
--- 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);
--- 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;
--- 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;
 
--- 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,
--- 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;
--- 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;
--- 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;
--- 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
Binary file share/hedgewars/Data/Graphics/AmmoMenu/BorderHorizontal.png has changed
Binary file share/hedgewars/Data/Graphics/AmmoMenu/BorderVertical.png has changed