[SCM] Worms style game branch, master, updated. upstream/0.9.19.2-4-g97105f8

Gianfranco Costamagna costamagnagianfranco at yahoo.it
Tue Jun 4 16:07:30 UTC 2013


The following commit has been merged in the master branch:
commit 30b174dc1b01cbd8b0c4b176268b30247072e3ec
Author: Gianfranco Costamagna <costamagnagianfranco at yahoo.it>
Date:   Tue Jun 4 17:45:29 2013 +0200

    Imported Upstream version 0.9.19.2

diff --git a/CMakeLists.txt b/CMakeLists.txt
index bb9c0e8..ed6542f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -24,7 +24,7 @@ option(NOPNG "Disable screenshoot compression (off)" OFF)
 option(NOVIDEOREC "Disable video recording (off)" OFF)
 
 #set this to ON when 2.1.0 becomes more widespread (and only for linux)
-option(SYSTEM_PHYSFS "Use system physfs (off)" OFF)
+option(PHYSFS_SYSTEM "Use system physfs (off)" OFF)
 
 option(BUILD_ENGINE_LIBRARY "Enable hwengine library (off)" OFF)
 option(ANDROID "Enable Android build (off)" OFF)
@@ -255,10 +255,10 @@ unset(CMAKE_REQUIRED_FLAGS)
 #parse additional parameters
 if(FPFLAGS OR GHFLAGS)
     if(${allow_parse_args})
-        message(${WARNING} "FPFLAGS and GHFLAGS are available only when using CMake >= 2.8")
-    else()
         separate_arguments(fpflags_parsed UNIX_COMMAND ${FPFLAGS})
         separate_arguments(ghflags_parsed UNIX_COMMAND ${GHFLAGS})
+    else()
+        message(${WARNING} "FPFLAGS and GHFLAGS are available only when using CMake >= 2.8")
     endif()
 endif()
 
@@ -315,7 +315,7 @@ endif()
 
 
 #physfs discovery
-if (${SYSTEM_PHYSFS})
+if (${PHYSFS_SYSTEM})
     if (NOT PHYSFS_LIBRARY OR NOT PHYSFS_INCLUDE_DIR)
         find_package(PhysFS)
     endif()
@@ -377,5 +377,5 @@ if(NOT ANDROID)
 endif()
 
 
-include(${CMAKE_MODULE_PATH}/CPackConfig.cmake)
+include(${CMAKE_MODULE_PATH}/cpackvars.cmake)
 
diff --git a/ChangeLog.txt b/ChangeLog.txt
index 70920c2..95d345c 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -32,7 +32,7 @@
  * Forbid kicking on 1v1 matches
  * Desync fixes
  * Fixed fort mode
- * Making very large maps now works properly with targetted weapons
+ * Making very large maps now works properly with targeted weapons
  * ParseCommand should be safe to use in Lua now, at any time
  * Fixes to many weapons. Mudball, blowtorch, explosives, cluster bomb spread, portal.
 
diff --git a/QTfrontend/KB.h b/QTfrontend/KB.h
deleted file mode 100644
index a687c5c..0000000
--- a/QTfrontend/KB.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at 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
- */
-
-#ifndef KB_H
-#define KB_H
-
-#include <QString>
-
-const ulong KBmsgsCount = 1;
-
-const QString KBMessages[KBmsgsCount] =
-{
-    QT_TRANSLATE_NOOP("KB", "SDL_ttf returned error while rendering text, "
-    "most propably it is related to the bug "
-    "in freetype2. It's recommended to update your "
-    "freetype lib.")
-};
-
-#endif // KB_H
diff --git a/QTfrontend/hedgewars.qrc.depends b/QTfrontend/hedgewars.qrc.depends
deleted file mode 100644
index 0e7ffc4..0000000
--- a/QTfrontend/hedgewars.qrc.depends
+++ /dev/null
@@ -1,157 +0,0 @@
-<RCC>
-    <qresource prefix="/">
-        <file alias="Ammos.png">../share/hedgewars/Data/Graphics/AmmoMenu/Ammos.png</file>
-        <file>res/css/qt.css</file>
-        <file>res/css/chat.css</file>
-        <file>res/css/christmas.css</file>
-        <file>res/css/easter.css</file>
-        <file>res/css/birthday.css</file>
-        <file>res/hh25x25.png</file>
-        <file>res/hh25x25grey.png</file>
-        <file>res/ammopic.png</file>
-        <file>res/ammopicgrey.png</file>
-        <file>res/ammopicbox.png</file>
-        <file>res/ammopicboxgrey.png</file>
-        <file>res/ammopicdelay.png</file>
-        <file>res/ammopicdelaygrey.png</file>
-        <file>res/infinity.png</file>
-        <file>res/infinitygrey.png</file>
-        <file>res/botlevels/0.png</file>
-        <file>res/botlevels/1.png</file>
-        <file>res/botlevels/2.png</file>
-        <file>res/botlevels/3.png</file>
-        <file>res/botlevels/4.png</file>
-        <file>res/botlevels/5.png</file>
-        <file>res/botlevels/net0.png</file>
-        <file>res/botlevels/net1.png</file>
-        <file>res/botlevels/net2.png</file>
-        <file>res/botlevels/net3.png</file>
-        <file>res/botlevels/net4.png</file>
-        <file>res/botlevels/net5.png</file>
-        <file>res/bonus.png</file>
-        <file>res/Hedgehog.png</file>
-        <file>res/net.png</file>
-        <file>res/About.png</file>
-        <file>res/SimpleGame.png</file>
-        <file>res/Campaign.png</file>
-        <file>res/Multiplayer.png</file>
-        <file>res/Trainings.png</file>
-        <file>res/Background.png</file>
-        <file>res/BackgroundChristmas.png</file>
-        <file>res/BackgroundEaster.png</file>
-        <file>res/BackgroundBirthday.png</file>
-        <file>res/Exit.png</file>
-        <file>res/HedgewarsTitle.png</file>
-        <file>res/LocalPlay.png</file>
-        <file>res/NetworkPlay.png</file>
-        <file>res/NetworkPlayDisabled.png</file>
-        <file>res/audio.png</file>
-        <file>res/camera.png</file>
-        <file>res/Settings.png</file>
-        <file>res/dropdown.png</file>
-        <file>res/new.png</file>
-        <file>res/edit.png</file>
-        <file>res/delete.png</file>
-        <file>res/checked.png</file>
-        <file>res/unchecked.png</file>
-        <file>res/graphicsicon.png</file>
-        <file>res/miscicon.png</file>
-        <file>res/Load.png</file>
-        <file>res/Save.png</file>
-        <file>res/Record.png</file>
-        <file>res/Videos.png</file>
-        <file>res/weaponsicon.png</file>
-        <file>res/teamicon.png</file>
-        <file>res/panelbg.png</file>
-        <file>res/lightbulb_on.png</file>
-        <file>res/lightbulb_off.png</file>
-        <file>res/spin_up.png</file>
-        <file>res/spin_down.png</file>
-        <file>res/PlaySound.png</file>
-        <file>res/hh_small.png</file>
-        <file>res/btnDisabled.png</file>
-        <file>res/btnForts at 2x.png</file>
-        <file>res/btnBorder at 2x.png</file>
-        <file>res/btnInvulnerable at 2x.png</file>
-        <file>res/btnLaserSight at 2x.png</file>
-        <file>res/btnLowGravity at 2x.png</file>
-        <file>res/btnResetHealth at 2x.png</file>
-        <file>res/btnTeamsDivide at 2x.png</file>
-        <file>res/btnSolid at 2x.png</file>
-        <file>res/btnVampiric at 2x.png</file>
-        <file>res/btnKarma at 2x.png</file>
-        <file>res/btnArtillery at 2x.png</file>
-        <file>res/btnRandomOrder at 2x.png</file>
-        <file>res/btnKing at 2x.png</file>
-        <file>res/btnPlaceHog at 2x.png</file>
-        <file>res/btnSharedAmmo at 2x.png</file>
-        <file>res/btnDisableGirders at 2x.png</file>
-        <file>res/btnDisableLandObjects at 2x.png</file>
-        <file>res/btnAISurvival at 2x.png</file>
-        <file>res/btnInfAttack at 2x.png</file>
-        <file>res/btnResetWeps at 2x.png</file>
-        <file>res/btnPerHogAmmo at 2x.png</file>
-        <file>res/btnNoWind at 2x.png</file>
-        <file>res/btnMoreWind at 2x.png</file>
-        <file>res/btnTagTeam at 2x.png</file>
-        <file>res/btnBottomBorder at 2x.png</file>
-        <file>res/iconBox.png</file>
-        <file>res/iconHealth.png</file>
-        <file>res/iconSuddenDeath.png</file>
-        <file>res/iconDamage.png</file>
-        <file>res/iconTime.png</file>
-        <file>res/iconMine.png</file>
-        <file>res/iconDud.png</file>
-        <file>res/iconRope.png</file>
-        <file>res/dice.png</file>
-        <file>res/Star.png</file>
-        <file>res/inverse-corner-bl.png</file>
-        <file>res/Flake.png</file>
-        <file>res/Egg.png</file>
-        <file>res/Confetti.png</file>
-        <file>res/file_save.png</file>
-        <file>res/file_demo.png</file>
-        <file>res/addfriend.png</file>
-        <file>res/remfriend.png</file>
-        <file>res/ignore.png</file>
-        <file>res/unignore.png</file>
-        <file>res/follow.png</file>
-        <file>res/info.png</file>
-        <file>res/kick.png</file>
-        <file>res/lock.png</file>
-        <file>res/unlock.png</file>
-        <file>res/StatsMedal1.png</file>
-        <file>res/StatsMedal2.png</file>
-        <file>res/StatsMedal3.png</file>
-        <file>res/StatsMedal4.png</file>
-        <file>res/StatsR.png</file>
-        <file>res/StatsH.png</file>
-        <file>res/StatsD.png</file>
-        <file>res/StatsBestKiller.png</file>
-        <file>res/StatsBestShot.png</file>
-        <file>res/StatsHedgehogsKilled.png</file>
-        <file>res/StatsMostSelfDamage.png</file>
-        <file>res/StatsSelfKilled.png</file>
-        <file>res/StatsSkipped.png</file>
-        <file>res/Start.png</file>
-        <file>res/mapRandom.png</file>
-        <file>res/mapMaze.png</file>
-        <file>res/mapMissing.png</file>
-        <file>res/mapCustom.png</file>
-        <file>res/mapMission.png</file>
-        <file>res/chat/friend.png</file>
-        <file>res/chat/ignore.png</file>
-        <file>res/chat/lamp.png</file>
-        <file>res/chat/hedgehog.png</file>
-        <file>res/chat/hedgehog_gray.png</file>
-        <file>res/chat/roomadmin.png</file>
-        <file>res/chat/roomadmin_gray.png</file>
-        <file>res/chat/serveradmin.png</file>
-        <file>res/chat/serveradmin_gray.png</file>
-        <file>res/chat/lamp_off.png</file>
-        <file>res/chat/ingame.png</file>
-        <file>res/splash.png</file>
-        <file>res/html/about.html</file>
-        <file>res/xml/tips.xml</file>
-    </qresource>
-</RCC>
diff --git a/QTfrontend/hwform.cpp b/QTfrontend/hwform.cpp
index dddaff5..c92b090 100644
--- a/QTfrontend/hwform.cpp
+++ b/QTfrontend/hwform.cpp
@@ -1374,6 +1374,9 @@ void HWForm::_NetConnect(const QString & hostName, quint16 port, QString nick)
     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()));
 
+    // using proxy slot to prevent loss of game messages when they're sent to not yet connected slot of game object
+    connect(hwnet, SIGNAL(FromNet(const QByteArray &)), this, SLOT(FromNetProxySlot(const QByteArray &)), Qt::QueuedConnection);
+
     //nick and pass stuff
     hwnet->m_private_game = !(hostName == NETGAME_DEFAULT_SERVER && port == NETGAME_DEFAULT_PORT);
     if (hwnet->m_private_game == false && AskForNickAndPwd() != 0)
@@ -1726,6 +1729,11 @@ void HWForm::StartCampaign()
 
 void HWForm::CreateNetGame()
 {
+    // go back in pages to prevent user from being stuck on certain pages
+    if(ui.Pages->currentIndex() == ID_PAGE_GAMESTATS ||
+       ui.Pages->currentIndex() == ID_PAGE_INGAME)
+        GoBack();
+
     QString ammo;
     ammo = ui.pageNetGame->pGameCFG->WeaponsName->itemData(
                ui.pageNetGame->pGameCFG->WeaponsName->currentIndex()
@@ -1736,7 +1744,6 @@ void HWForm::CreateNetGame()
     connect(game, SIGNAL(SendNet(const QByteArray &)), hwnet, SLOT(SendNet(const QByteArray &)));
     connect(game, SIGNAL(SendChat(const QString &)), hwnet, SLOT(chatLineToNet(const QString &)));
     connect(game, SIGNAL(SendTeamMessage(const QString &)), hwnet, SLOT(SendTeamMessage(const QString &)));
-    connect(hwnet, SIGNAL(FromNet(const QByteArray &)), game, SLOT(FromNet(const QByteArray &)), Qt::QueuedConnection);
     connect(hwnet, SIGNAL(chatStringFromNet(const QString &)), game, SLOT(FromNetChat(const QString &)), Qt::QueuedConnection);
 
     game->StartNet();
@@ -1828,6 +1835,13 @@ void HWForm::NetGameSlave()
     ui.pageNetGame->setMasterMode(false);
 }
 
+void HWForm::FromNetProxySlot(const QByteArray & msg)
+{
+    if(game)
+        game->FromNet(msg);
+
+}
+
 void HWForm::selectFirstNetScheme()
 {
     ui.pageNetGame->pGameCFG->GameSchemes->setCurrentIndex(0);
diff --git a/QTfrontend/hwform.h b/QTfrontend/hwform.h
index 35fc424..fc7bc38 100644
--- a/QTfrontend/hwform.h
+++ b/QTfrontend/hwform.h
@@ -145,6 +145,8 @@ class HWForm : public QMainWindow
         void startGame();
         void restartGame();
 
+        void FromNetProxySlot(const QByteArray &);
+
     private:
         void _NetConnect(const QString & hostName, quint16 port, QString nick);
         int  AskForNickAndPwd(void);
diff --git a/QTfrontend/res/css/qt.css b/QTfrontend/res/css/qt.css
index bd4bf93..26b3c2c 100644
--- a/QTfrontend/res/css/qt.css
+++ b/QTfrontend/res/css/qt.css
@@ -176,15 +176,10 @@ width: 16px;
 height: 10px;
 }
 
-QLabel {
-overflow: hidden;
-}
-
 QComboBox {
 border-radius: 10px;
 padding: 3px;
 height: 18px;
-overflow: hidden;
 }
 QComboBox:pressed{
 border-color: white;
diff --git a/QTfrontend/servermessages.h b/QTfrontend/servermessages.h
index a93e011..bc1c372 100644
--- a/QTfrontend/servermessages.h
+++ b/QTfrontend/servermessages.h
@@ -1,30 +1,30 @@
-const char * serverMessages[] = {
-QT_TRANSLATE_NOOP("server", "Nickname already chosen"),
-QT_TRANSLATE_NOOP("server", "Illegal nickname"),
-QT_TRANSLATE_NOOP("server", "Protocol already known"),
-QT_TRANSLATE_NOOP("server", "Bad number"),
-QT_TRANSLATE_NOOP("server", "Nickname is already in use"),
-QT_TRANSLATE_NOOP("server", "No checker rights"),
-QT_TRANSLATE_NOOP("server", "Authentication failed"),
-QT_TRANSLATE_NOOP("server", "60 seconds cooldown after kick"),
-QT_TRANSLATE_NOOP("server", "kicked"),
-QT_TRANSLATE_NOOP("server", "Ping timeout"),
-QT_TRANSLATE_NOOP("server", "Empty config entry"),
-QT_TRANSLATE_NOOP("server", "Not room master"),
-QT_TRANSLATE_NOOP("server", "Corrupted hedgehogs info"),
-QT_TRANSLATE_NOOP("server", "too many teams"),
-QT_TRANSLATE_NOOP("server", "too many hedgehogs"),
-QT_TRANSLATE_NOOP("server", "There's already a team with same name in the list"),
-QT_TRANSLATE_NOOP("server", "round in progress"),
-QT_TRANSLATE_NOOP("server", "restricted"),
-QT_TRANSLATE_NOOP("server", "REMOVE_TEAM: no such team"),
-QT_TRANSLATE_NOOP("server", "Not team owner!"),
-QT_TRANSLATE_NOOP("server", "Less than two clans!"),
-QT_TRANSLATE_NOOP("server", "Room with such name already exists"),
-QT_TRANSLATE_NOOP("server", "Illegal room name"),
-QT_TRANSLATE_NOOP("server", "No such room"),
-QT_TRANSLATE_NOOP("server", "Joining restricted"),
-QT_TRANSLATE_NOOP("server", "Registered users only"),
-QT_TRANSLATE_NOOP("server", "You are banned in this room"),
-QT_TRANSLATE_NOOP("server", "bye")
-};
+const char * serverMessages[] = {
+QT_TRANSLATE_NOOP("server", "No checker rights"),
+QT_TRANSLATE_NOOP("server", "Authentication failed"),
+QT_TRANSLATE_NOOP("server", "60 seconds cooldown after kick"),
+QT_TRANSLATE_NOOP("server", "kicked"),
+QT_TRANSLATE_NOOP("server", "Ping timeout"),
+QT_TRANSLATE_NOOP("server", "bye"),
+QT_TRANSLATE_NOOP("server", "Empty config entry"),
+QT_TRANSLATE_NOOP("server", "Not room master"),
+QT_TRANSLATE_NOOP("server", "Corrupted hedgehogs info"),
+QT_TRANSLATE_NOOP("server", "too many teams"),
+QT_TRANSLATE_NOOP("server", "too many hedgehogs"),
+QT_TRANSLATE_NOOP("server", "There's already a team with same name in the list"),
+QT_TRANSLATE_NOOP("server", "round in progress"),
+QT_TRANSLATE_NOOP("server", "restricted"),
+QT_TRANSLATE_NOOP("server", "REMOVE_TEAM: no such team"),
+QT_TRANSLATE_NOOP("server", "Not team owner!"),
+QT_TRANSLATE_NOOP("server", "Less than two clans!"),
+QT_TRANSLATE_NOOP("server", "Room with such name already exists"),
+QT_TRANSLATE_NOOP("server", "Illegal room name"),
+QT_TRANSLATE_NOOP("server", "No such room"),
+QT_TRANSLATE_NOOP("server", "Joining restricted"),
+QT_TRANSLATE_NOOP("server", "Registered users only"),
+QT_TRANSLATE_NOOP("server", "You are banned in this room"),
+QT_TRANSLATE_NOOP("server", "Nickname already chosen"),
+QT_TRANSLATE_NOOP("server", "Illegal nickname"),
+QT_TRANSLATE_NOOP("server", "Protocol already known"),
+QT_TRANSLATE_NOOP("server", "Bad number"),
+QT_TRANSLATE_NOOP("server", "Nickname is already in use")
+};
diff --git a/cmake_modules/CPackConfig.cmake b/cmake_modules/CPackConfig.cmake
deleted file mode 100644
index c1aa7b2..0000000
--- a/cmake_modules/CPackConfig.cmake
+++ /dev/null
@@ -1,98 +0,0 @@
-
-# revision information in cpack-generated names
-if(CMAKE_BUILD_TYPE MATCHES DEBUG)
-    set(full_suffix "${HEDGEWARS_VERSION}-r${HEDGEWARS_REVISION}")
-else()
-    set(full_suffix "${HEDGEWARS_VERSION}")
-endif()
-
-# CPack variables
-set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Hedgewars, a free turn-based strategy game")
-set(CPACK_PACKAGE_VENDOR "Hedgewars Project")
-set(CPACK_PACKAGE_FILE_NAME "Hedgewars-${full_suffix}")
-set(CPACK_SOURCE_PACKAGE_FILE_NAME "hedgewars-src-${full_suffix}")
-set(CPACK_SOURCE_GENERATOR "TBZ2")
-set(CPACK_PACKAGE_EXECUTABLES "hedgewars" "Hedgewars")
-set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING")
-set(CPACK_PACKAGE_INSTALL_DIRECTORY "Hedgewars ${full_suffix}")
-set(CPACK_STRIP_FILES true)
-
-if(WIN32 AND NOT UNIX)
-    set(CPACK_NSIS_DISPLAY_NAME "Hedgewars")
-    set(CPACK_NSIS_HELP_LINK "http://www.hedgewars.org/")
-    set(CPACK_NSIS_URL_INFO_ABOUT "http://www.hedgewars.org/")
-    set(CPACK_NSIS_CONTACT "unC0Rr at gmail.com")
-    set(CPACK_NSIS_MODIFY_PATH OFF)
-    set(CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
-    set(CPACK_NSIS_MUI_FINISHPAGE_RUN "hedgewars${CMAKE_EXECUTABLE_SUFFIX}")
-    set(CPACK_NSIS_CREATE_ICONS "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Hedgewars.lnk' '$INSTDIR\\\\hedgewars.exe'")
-    set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "hedgewars")
-endif(WIN32 AND NOT UNIX)
-
-set(CPACK_SOURCE_IGNORE_FILES
-    #temporary files
-    "~"
-    ".swp"
-    #version control
-    "\\\\.hg"
-    #output binary/library
-    "\\\\.exe$"
-    "\\\\.a$"
-    "\\\\.so$"
-    "\\\\.dylib$"
-    "\\\\.dll$"
-    "\\\\.ppu$"
-    "\\\\.o$"
-    "\\\\.cxx$"
-    #graphics
-    "\\\\.xcf$"
-    "\\\\.svg$"
-    "\\\\.svgz$"
-    "\\\\.psd$"
-    "\\\\.sifz$"
-    #misc
-    "\\\\.core$"
-    "\\\\.sh$"
-    "\\\\.orig$"
-    "\\\\.layout$"
-    "\\\\.db$"
-    "\\\\.dof$"
-    #archives
-    "\\\\.zip$"
-    "\\\\.gz$"
-    "\\\\.bz2$"
-    "\\\\.tmp$"
-    #cmake-configured files
-    "hwconsts\\\\.cpp$"
-    "config\\\\.inc$"
-    "hwengine\\\\.desktop$"
-    "Info\\\\.plist$"
-    #other cmake generated files
-    "Makefile"
-    "Doxyfile"
-    "CMakeFiles"
-    "[dD]ebug$"
-    "[rR]elease$"
-    "CPack"
-    "cmake_install\\\\.cmake$"
-    "CMakeCache\\\\.txt$"
-#    "^${CMAKE_CURRENT_SOURCE_DIR}/misc/libtremor"
-#    "^${CMAKE_CURRENT_SOURCE_DIR}/misc/libfreetype"
-#    "^${CMAKE_CURRENT_SOURCE_DIR}/misc/liblua"
-    "^${CMAKE_CURRENT_SOURCE_DIR}/misc/libopenalbridge"
-    "^${CMAKE_CURRENT_SOURCE_DIR}/project_files/frontlib"
-    "^${CMAKE_CURRENT_SOURCE_DIR}/project_files/promotional_art"
-    "^${CMAKE_CURRENT_SOURCE_DIR}/project_files/cmdlineClient"
-    "^${CMAKE_CURRENT_SOURCE_DIR}/tools/templates"
-    "^${CMAKE_CURRENT_SOURCE_DIR}/bin/checkstack*"
-    "^${CMAKE_CURRENT_SOURCE_DIR}/doc"
-    "^${CMAKE_CURRENT_SOURCE_DIR}/templates"
-    "^${CMAKE_CURRENT_SOURCE_DIR}/tmp"
-    "^${CMAKE_CURRENT_SOURCE_DIR}/utils"
-    "^${CMAKE_CURRENT_SOURCE_DIR}/share/hedgewars/Data/Maps/test"
-    "^${CMAKE_CURRENT_SOURCE_DIR}/install_manifest.txt"
-    "^${CMAKE_CURRENT_SOURCE_DIR}/CMakeCache.txt"
-    "^${CMAKE_CURRENT_SOURCE_DIR}/hedgewars\\\\."
-)
-
-include(CPack)
diff --git a/cmake_modules/cpackvars.cmake b/cmake_modules/cpackvars.cmake
new file mode 100644
index 0000000..bd88f72
--- /dev/null
+++ b/cmake_modules/cpackvars.cmake
@@ -0,0 +1,105 @@
+
+# revision information in cpack-generated names
+if(CMAKE_BUILD_TYPE MATCHES DEBUG)
+    set(full_suffix "${HEDGEWARS_VERSION}-r${HEDGEWARS_REVISION}")
+else()
+    set(full_suffix "${HEDGEWARS_VERSION}")
+endif()
+
+# CPack variables
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Hedgewars, a free turn-based strategy game")
+set(CPACK_PACKAGE_VENDOR "Hedgewars Project")
+set(CPACK_PACKAGE_FILE_NAME "Hedgewars-${full_suffix}")
+set(CPACK_SOURCE_PACKAGE_FILE_NAME "hedgewars-src-${full_suffix}")
+set(CPACK_SOURCE_GENERATOR "TBZ2")
+set(CPACK_PACKAGE_EXECUTABLES "hedgewars" "Hedgewars")
+set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING")
+set(CPACK_PACKAGE_INSTALL_DIRECTORY "Hedgewars ${full_suffix}")
+set(CPACK_STRIP_FILES true)
+
+if(WIN32 AND NOT UNIX)
+    set(CPACK_NSIS_DISPLAY_NAME "Hedgewars")
+    set(CPACK_NSIS_HELP_LINK "http://www.hedgewars.org/")
+    set(CPACK_NSIS_URL_INFO_ABOUT "http://www.hedgewars.org/")
+    set(CPACK_NSIS_CONTACT "unC0Rr at gmail.com")
+    set(CPACK_NSIS_MODIFY_PATH OFF)
+    set(CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
+    set(CPACK_NSIS_MUI_FINISHPAGE_RUN "hedgewars${CMAKE_EXECUTABLE_SUFFIX}")
+    set(CPACK_NSIS_CREATE_ICONS "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Hedgewars.lnk' '$INSTDIR\\\\hedgewars.exe'")
+    set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "hedgewars")
+endif(WIN32 AND NOT UNIX)
+
+set(CPACK_SOURCE_IGNORE_FILES
+    #temporary files
+    "~"
+    ".swp"
+    #version control
+    "\\\\.hg"
+    "\\\\.orig$"
+    #output binary/library
+    "\\\\.exe$"
+    "\\\\.a$"
+    "\\\\.so$"
+    "\\\\.dylib$"
+    "\\\\.dll$"
+    "\\\\.ppu$"
+    "\\\\.o$"
+    "\\\\.cxx$"
+    "\\\\.hi$"
+    #graphics
+    "\\\\.xcf$"
+    "\\\\.svg$"
+    "\\\\.svgz$"
+    "\\\\.psd$"
+    "\\\\.sifz$"
+    #misc
+    "\\\\.core$"
+    "\\\\.layout$"
+    "\\\\.db$"
+    "\\\\.dof$"
+    "\\\\.or$"
+    #archives
+    "\\\\.zip$"
+    "\\\\.gz$"
+    "\\\\.bz2$"
+    "\\\\.tmp$"
+    #cmake-configured files
+    "hwconsts\\\\.cpp$"
+    "config\\\\.inc$"
+    "hwengine\\\\.desktop$"
+    "Info\\\\.plist$"
+    #qt extra files
+    "moc_.*\\\\.cxx_parameters"
+    "\\\\.qrc.depends$"
+    "\\\\.qm$"
+    #other cmake generated files
+    "Makefile$"
+    "Doxyfile"
+    "CMakeFiles"
+    "[dD]ebug$"
+    "[rR]elease$"
+    "CPack"
+    "cmake_install\\\\.cmake$"
+    "cmake_uninstall\\\\.cmake$"
+    "CMakeCache\\\\.txt$"
+    "build_windows_.*\\\\.bat$"
+#    "^${CMAKE_CURRENT_SOURCE_DIR}/misc/libtremor"
+#    "^${CMAKE_CURRENT_SOURCE_DIR}/misc/libfreetype"
+#    "^${CMAKE_CURRENT_SOURCE_DIR}/misc/liblua"
+#    "^${CMAKE_CURRENT_SOURCE_DIR}/project_files/frontlib"
+#    "^${CMAKE_CURRENT_SOURCE_DIR}/project_files/cmdlineClient"
+    "^${CMAKE_CURRENT_SOURCE_DIR}/misc/libopenalbridge"
+    "^${CMAKE_CURRENT_SOURCE_DIR}/misc/winutils/bin"
+    "^${CMAKE_CURRENT_SOURCE_DIR}/project_files/promotional_art"
+    "^${CMAKE_CURRENT_SOURCE_DIR}/tools/templates"
+    "^${CMAKE_CURRENT_SOURCE_DIR}/tools/drawMapTest"
+    "^${CMAKE_CURRENT_SOURCE_DIR}/doc"
+    "^${CMAKE_CURRENT_SOURCE_DIR}/tmp"
+    "^${CMAKE_CURRENT_SOURCE_DIR}/utils"
+    "^${CMAKE_CURRENT_SOURCE_DIR}/share/hedgewars/Data/Maps/test"
+    "^${CMAKE_CURRENT_SOURCE_DIR}/install_manifest.txt"
+    "^${CMAKE_CURRENT_SOURCE_DIR}/CMakeCache.txt"
+    "^${CMAKE_CURRENT_SOURCE_DIR}/hedgewars\\\\."
+)
+
+include(CPack)
diff --git a/hedgewars/GL.h b/hedgewars/GL.h
deleted file mode 100644
index 6a18374..0000000
--- a/hedgewars/GL.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-#include <GL/gl.h>
diff --git a/hedgewars/Math.h b/hedgewars/Math.h
deleted file mode 100644
index 3f59c93..0000000
--- a/hedgewars/Math.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#pragma once
-
diff --git a/hedgewars/SDLh.pas b/hedgewars/SDLh.pas
index 7a85f75..d434bb4 100644
--- a/hedgewars/SDLh.pas
+++ b/hedgewars/SDLh.pas
@@ -35,12 +35,6 @@ interface
 {$ENDIF}
 
 {$IFDEF UNIX}
-    {$IFNDEF DARWIN}
-        {necessary for statically linking physfs (divdi3 undefined on 32 bit)}
-        {$IFDEF CPU32}
-            {$linklib stdc++}
-        {$ENDIF}
-    {$ENDIF}
     {$IFDEF HAIKU}
         {$linklib root}
     {$ELSE}
diff --git a/hedgewars/SysUtils.h b/hedgewars/SysUtils.h
deleted file mode 100644
index e69de29..0000000
diff --git a/hedgewars/Types.h b/hedgewars/Types.h
deleted file mode 100644
index e69de29..0000000
diff --git a/hedgewars/hwengine.res b/hedgewars/hwengine.res
new file mode 100644
index 0000000..b8b1641
Binary files /dev/null and b/hedgewars/hwengine.res differ
diff --git a/hedgewars/uPhysFSLayer.pas b/hedgewars/uPhysFSLayer.pas
index 286afbd..82737a4 100644
--- a/hedgewars/uPhysFSLayer.pas
+++ b/hedgewars/uPhysFSLayer.pas
@@ -11,18 +11,8 @@ const PhyslayerLibName = 'libphyslayer';
     {$linklib physlayer}
 
     {statically linking physfs brings IOKit dependency on OSX}
-    {divdi3 is found in stdc++ on linux x86 and in gcc_s.1 on osx ppc32}
-    {$IFDEF PHYSFS_INTERNAL}
-        {$IFDEF DARWIN}
-            {$linkframework IOKit}
-            {$IFDEF CPU32}
-                {$linklib gcc_s.1}
-            {$ENDIF}
-        {$ELSE}
-            {$IFDEF CPU32}
-                {$linklib stdc++}
-            {$ENDIF}
-        {$ENDIF}
+    {$IFDEF DARWIN}
+        {$linkframework IOKit}
     {$ENDIF}
 {$ENDIF}
 
diff --git a/misc/libfreetype/autogen.sh b/misc/libfreetype/autogen.sh
new file mode 100644
index 0000000..c28a51c
--- /dev/null
+++ b/misc/libfreetype/autogen.sh
@@ -0,0 +1,163 @@
+#!/bin/sh
+
+# Copyright 2005, 2006, 2007, 2008, 2009, 2010 by
+# David Turner, Robert Wilhelm, and Werner Lemberg.
+#
+# This file is part of the FreeType project, and may only be used, modified,
+# and distributed under the terms of the FreeType project license,
+# LICENSE.TXT.  By continuing to use, modify, or distribute this file you
+# indicate that you have read the license and understand and accept it
+# fully.
+
+run ()
+{
+  echo "running \`$*'"
+  eval $*
+
+  if test $? != 0 ; then
+    echo "error while running \`$*'"
+    exit 1
+  fi
+}
+
+get_major_version ()
+{
+  echo $1 | sed -e 's/\([0-9][0-9]*\)\..*/\1/g'
+}
+
+get_minor_version ()
+{
+  echo $1 | sed -e 's/[0-9][0-9]*\.\([0-9][0-9]*\).*/\1/g'
+}
+
+get_patch_version ()
+{
+  # tricky: some version numbers don't include a patch
+  # separated with a point, but something like 1.4-p6
+  patch=`echo $1 | sed -e 's/[0-9][0-9]*\.[0-9][0-9]*\.\([0-9][0-9]*\).*/\1/g'`
+  if test "$patch" = "$1"; then
+    patch=`echo $1 | sed -e 's/[0-9][0-9]*\.[0-9][0-9]*\-p\([0-9][0-9]*\).*/\1/g'`
+    # if there isn't any patch number, default to 0
+    if test "$patch" = "$1"; then
+      patch=0
+    fi
+  fi
+  echo $patch
+}
+
+# $1: version to check
+# $2: minimum version
+
+compare_to_minimum_version ()
+{
+  MAJOR1=`get_major_version $1`
+  MAJOR2=`get_major_version $2`
+  if test $MAJOR1 -lt $MAJOR2; then
+    echo 0
+    return
+  else 
+    if test $MAJOR1 -gt $MAJOR2; then
+      echo 1
+      return
+    fi
+  fi
+
+  MINOR1=`get_minor_version $1`
+  MINOR2=`get_minor_version $2`
+  if test $MINOR1 -lt $MINOR2; then
+    echo 0
+    return
+  else 
+    if test $MINOR1 -gt $MINOR2; then
+      echo 1
+      return
+    fi
+  fi
+
+  PATCH1=`get_patch_version $1`
+  PATCH2=`get_patch_version $2`
+  if test $PATCH1 -lt $PATCH2; then
+    echo 0
+  else
+    echo 1
+  fi
+}
+
+# check the version of a given tool against a minimum version number
+#
+# $1: tool path
+# $2: tool usual name (e.g. `aclocal')
+# $3: tool variable  (e.g. `ACLOCAL')
+# $4: minimum version to check against
+# $5: option field index used to extract the tool version from the
+#     output of --version
+
+check_tool_version ()
+{
+  field=$5
+  # assume the output of "[TOOL] --version" is "toolname (GNU toolname foo bar) version"
+  if test "$field"x = x; then
+    field=3  # default to 3 for all GNU autotools, after filtering enclosed string
+  fi
+  version=`$1 --version | head -1 | sed 's/([^)]*)/()/g' | cut -d ' ' -f $field`
+  version_check=`compare_to_minimum_version $version $4`
+  if test "$version_check"x = 0x; then
+    echo "ERROR: Your version of the \`$2' tool is too old."
+    echo "       Minimum version $4 is required (yours is version $version)."
+    echo "       Please upgrade or use the $3 variable to point to a more recent one."
+    echo ""
+    exit 1
+  fi
+}
+
+if test ! -f ./builds/unix/configure.raw; then
+  echo "You must be in the same directory as \`autogen.sh'."
+  echo "Bootstrapping doesn't work if srcdir != builddir."
+  exit 1
+fi
+
+# On MacOS X, the GNU libtool is named `glibtool'.
+HOSTOS=`uname`
+LIBTOOLIZE=libtoolize
+if test "$HOSTOS"x = Darwinx; then
+  LIBTOOLIZE=glibtoolize
+fi
+
+if test "$ACLOCAL"x = x; then
+  ACLOCAL=aclocal
+fi
+
+if test "$AUTOCONF"x = x; then
+  AUTOCONF=autoconf
+fi
+
+check_tool_version $ACLOCAL    aclocal    ACLOCAL    1.10.1
+check_tool_version $LIBTOOLIZE libtoolize LIBTOOLIZE 2.2.4
+check_tool_version $AUTOCONF   autoconf   AUTOCONF   2.62
+
+# This sets freetype_major, freetype_minor, and freetype_patch.
+eval `sed -nf version.sed include/freetype/freetype.h`
+
+# We set freetype-patch to an empty value if it is zero.
+if test "$freetype_patch" = ".0"; then
+  freetype_patch=
+fi
+
+cd builds/unix
+
+echo "generating \`configure.ac'"
+sed -e "s;@VERSION@;$freetype_major$freetype_minor$freetype_patch;" \
+  < configure.raw > configure.ac
+
+run aclocal -I . --force
+run $LIBTOOLIZE --force --copy --install
+run autoconf --force
+
+chmod +x mkinstalldirs
+chmod +x install-sh
+
+cd ../..
+
+chmod +x ./configure
+
+# EOF
diff --git a/misc/libfreetype/builds/atari/gen-purec-patch.sh b/misc/libfreetype/builds/atari/gen-purec-patch.sh
new file mode 100644
index 0000000..1ec050c
--- /dev/null
+++ b/misc/libfreetype/builds/atari/gen-purec-patch.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+TOP_DIR=.
+OBJ_DIR=.
+
+for x in "$@"
+do
+  case x"$x" in
+  x--srcdir=* | x--topdir=* )
+    TOP_DIR=`echo $x | sed 's/^--[a-z]*dir=//'`
+    ;;
+  x--builddir=* | x--objdir=* )
+    OBJ_DIR=`echo $x | sed 's/^--[a-z]*dir=//'`
+    ;;
+  esac
+done
+
+mkdir -p ${OBJ_DIR}/builds/atari/tmp/orig
+
+( cd ${TOP_DIR} && find . -name '*.[CHch]' -type f | fgrep -v builds/atari/tmp | cpio -o ) | \
+( cd ${OBJ_DIR}/builds/atari/tmp/orig && cpio -idum )
+cp ${TOP_DIR}/builds/atari/deflinejoiner.awk ${OBJ_DIR}/builds/atari/tmp
+
+pushd ${OBJ_DIR}/builds/atari/tmp
+
+  cp -pr orig purec
+  for f in `cd orig && find . -type f`
+  do
+    echo filter $f
+    env LANG=C awk -f deflinejoiner.awk < orig/$f > purec/$f
+  done
+
+  echo '#define FT2_BUILD_LIBRARY'  >  purec/include/ft2build.h
+  echo '#include "ATARI.H"'         >> purec/include/ft2build.h
+  env LANG=C awk -f deflinejoiner.awk < orig/include/ft2build.h >> purec/include/ft2build.h
+
+  env LANG=C diff -ur orig purec > ../purec.diff
+
+popd
+rm -rf ${OBJ_DIR}/builds/atari/tmp
diff --git a/misc/libphysfs/CMakeLists.txt b/misc/libphysfs/CMakeLists.txt
index 5130b5b..e951630 100644
--- a/misc/libphysfs/CMakeLists.txt
+++ b/misc/libphysfs/CMakeLists.txt
@@ -35,6 +35,15 @@ include(CheckLibraryExists)
 include(CheckCSourceCompiles)
 
 
+# 32bit platforms won't link unless this is set
+# although Windows doesn't like it
+if(NOT WINDOWS)
+    if(CMAKE_SIZEOF_VOID_P LESS 8)
+        add_definitions(-DPHYSFS_NO_64BIT_SUPPORT=1)
+    endif(CMAKE_SIZEOF_VOID_P LESS 8)
+endif(NOT WINDOWS)
+
+
 if(MACOSX)
     # Fallback to older OS X on PowerPC to support wider range of systems...
     if(CMAKE_OSX_ARCHITECTURES MATCHES ppc)
diff --git a/misc/libphysfs/physfs_internal.h b/misc/libphysfs/physfs_internal.h
index 1dec63f..c99e424 100644
--- a/misc/libphysfs/physfs_internal.h
+++ b/misc/libphysfs/physfs_internal.h
@@ -322,8 +322,13 @@ void __PHYSFS_sort(void *entries, size_t max,
 #define __PHYSFS_ARRAYLEN(x) ( (sizeof (x)) / (sizeof (x[0])) )
 
 #ifdef PHYSFS_NO_64BIT_SUPPORT
-#define __PHYSFS_SI64(x) ((PHYSFS_sint64) (x))
-#define __PHYSFS_UI64(x) ((PHYSFS_uint64) (x))
+/* if a 32bit compiler sees something with this many bits: 0xFFFFFFFFFFFFFFFF
+ *  it doesn't know if it really means 64bit or if it's supposed to squeeze
+ *  it into 32 bit, so without the ULL it squeezes the number to 32 bit,
+ *  with it it forces it to be 64bits
+ */
+#define __PHYSFS_SI64(x) ((PHYSFS_sint64) (x##LL))
+#define __PHYSFS_UI64(x) ((PHYSFS_uint64) (x##ULL))
 #elif (defined __GNUC__)
 #define __PHYSFS_SI64(x) x##LL
 #define __PHYSFS_UI64(x) x##ULL
diff --git a/misc/libtremor/tremor/Makefile.am b/misc/libtremor/tremor/Makefile.am
new file mode 100644
index 0000000..d14081f
--- /dev/null
+++ b/misc/libtremor/tremor/Makefile.am
@@ -0,0 +1,38 @@
+AUTOMAKE_OPTIONS = foreign
+
+INCLUDES = -I./
+
+lib_LTLIBRARIES = libvorbisidec.la
+
+libvorbisidec_la_SOURCES = mdct.c block.c window.c \
+                        synthesis.c info.c \
+                        floor1.c floor0.c vorbisfile.c \
+                        res012.c mapping0.c registry.c codebook.c \
+			sharedbook.c framing.c bitwise.c \
+                        codebook.h misc.h mdct_lookup.h\
+                        os.h mdct.h block.h ivorbisfile.h lsp_lookup.h\
+                        registry.h window.h window_lookup.h\
+                        codec_internal.h backends.h ogg.h \
+			asm_arm.h ivorbiscodec.h
+libvorbisidec_la_LDFLAGS = -version-info @V_LIB_CURRENT@:@V_LIB_REVISION@:@V_LIB_AGE@
+
+EXTRA_PROGRAMS = ivorbisfile_example
+CLEANFILES = $(EXTRA_PROGRAMS) $(lib_LTLIBRARIES)
+
+ivorbisfile_example_SOURCES = ivorbisfile_example.c
+ivorbisfile_example_LDFLAGS = -static 
+ivorbisfile_example_LDADD = libvorbisidec.la
+
+includedir = $(prefix)/include/tremor
+
+include_HEADERS = ivorbiscodec.h ivorbisfile.h ogg.h os_types.h config_types.h
+
+example:
+	-ln -fs . vorbis
+	$(MAKE) ivorbisfile_example
+
+debug:
+	$(MAKE) all CFLAGS="@DEBUG@" 
+
+profile:
+	$(MAKE) all CFLAGS="@PROFILE@"
diff --git a/misc/libtremor/tremor/autogen.sh b/misc/libtremor/tremor/autogen.sh
new file mode 100644
index 0000000..73c8fca
--- /dev/null
+++ b/misc/libtremor/tremor/autogen.sh
@@ -0,0 +1,120 @@
+#!/bin/sh
+# Run this to set up the build system: configure, makefiles, etc.
+# (based on the version in enlightenment's cvs)
+
+package="vorbisdec"
+
+olddir=`pwd`
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+cd "$srcdir"
+DIE=0
+
+echo "checking for autoconf... "
+(autoconf --version) < /dev/null > /dev/null 2>&1 || {
+        echo
+        echo "You must have autoconf installed to compile $package."
+        echo "Download the appropriate package for your distribution,"
+        echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
+        DIE=1
+}
+
+VERSIONGREP="sed -e s/.*[^0-9\.]\([0-9]\.[0-9]\).*/\1/"
+VERSIONMKINT="sed -e s/[^0-9]//"
+                                                                                
+# do we need automake?
+if test -r Makefile.am; then
+  AM_OPTIONS=`fgrep AUTOMAKE_OPTIONS Makefile.am`
+  AM_NEEDED=`echo $AM_OPTIONS | $VERSIONGREP`
+  if test x"$AM_NEEDED" = "x$AM_OPTIONS"; then
+    AM_NEEDED=""
+  fi
+  if test -z $AM_NEEDED; then
+    echo -n "checking for automake... "
+    AUTOMAKE=automake
+    ACLOCAL=aclocal
+    if ($AUTOMAKE --version < /dev/null > /dev/null 2>&1); then
+      echo "yes"
+    else
+      echo "no"
+      AUTOMAKE=
+    fi
+  else
+    echo -n "checking for automake $AM_NEEDED or later... "
+    for am in automake-$AM_NEEDED automake$AM_NEEDED automake; do
+      ($am --version < /dev/null > /dev/null 2>&1) || continue
+      ver=`$am --version < /dev/null | head -n 1 | $VERSIONGREP | $VERSIONMKINT`
+      verneeded=`echo $AM_NEEDED | $VERSIONMKINT`
+      if test $ver -ge $verneeded; then
+        AUTOMAKE=$am
+        echo $AUTOMAKE
+        break
+      fi
+    done
+    test -z $AUTOMAKE &&  echo "no"
+    echo -n "checking for aclocal $AM_NEEDED or later... "
+    for ac in aclocal-$AM_NEEDED aclocal$AM_NEEDED aclocal; do
+      ($ac --version < /dev/null > /dev/null 2>&1) || continue
+      ver=`$ac --version < /dev/null | head -n 1 | $VERSIONGREP | $VERSIONMKINT`
+      verneeded=`echo $AM_NEEDED | $VERSIONMKINT`
+      if test $ver -ge $verneeded; then
+        ACLOCAL=$ac
+        echo $ACLOCAL
+        break
+      fi
+    done
+    test -z $ACLOCAL && echo "no"
+  fi
+  test -z $AUTOMAKE || test -z $ACLOCAL && {
+        echo
+        echo "You must have automake installed to compile $package."
+        echo "Download the appropriate package for your distribution,"
+        echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
+        exit 1
+  }
+fi
+
+echo -n "checking for libtool... "
+for LIBTOOLIZE in libtoolize glibtoolize nope; do
+  ($LIBTOOLIZE --version) < /dev/null > /dev/null 2>&1 && break
+done
+if test x$LIBTOOLIZE = xnope; then
+  echo "nope."
+  LIBTOOLIZE=libtoolize
+else
+  echo $LIBTOOLIZE
+fi
+($LIBTOOLIZE --version) < /dev/null > /dev/null 2>&1 || {
+	echo
+	echo "You must have libtool installed to compile $package."
+	echo "Download the appropriate package for your system,"
+	echo "or get the source from one of the GNU ftp sites"
+	echo "listed in http://www.gnu.org/order/ftp.html"
+	DIE=1
+}
+
+if test "$DIE" -eq 1; then
+        exit 1
+fi
+
+if test -z "$*"; then
+        echo "I am going to run ./configure with no arguments - if you wish "
+        echo "to pass any to it, please specify them on the $0 command line."
+fi
+
+echo "Generating configuration files for $package, please wait...."
+
+echo "  $ACLOCAL $ACLOCAL_FLAGS"
+$ACLOCAL $ACLOCAL_FLAGS || exit 1
+echo "  $LIBTOOLIZE --automake"
+$LIBTOOLIZE --automake || exit 1
+echo "  autoheader"
+autoheader || exit 1
+echo "  $AUTOMAKE --add-missing $AUTOMAKE_FLAGS"
+$AUTOMAKE --add-missing $AUTOMAKE_FLAGS || exit 1
+echo "  autoconf"
+autoconf || exit 1
+
+cd $olddir
+$srcdir/configure --enable-maintainer-mode "$@" && echo
diff --git a/project_files/Android-build/SDL-android-project/assets/Data/Locale/hedgewars_en.qm b/project_files/Android-build/SDL-android-project/assets/Data/Locale/hedgewars_en.qm
deleted file mode 100644
index 977fe60..0000000
Binary files a/project_files/Android-build/SDL-android-project/assets/Data/Locale/hedgewars_en.qm and /dev/null differ
diff --git a/project_files/Android-build/SDL-android-project/jni/SDL/src/file/SDL_rwops.c b/project_files/Android-build/SDL-android-project/jni/SDL/src/file/SDL_rwops.c
old mode 100755
new mode 100644
diff --git a/project_files/Android-build/SDL-android-project/jni/SDL/src/video/android/SDL_androidkeyboard.c b/project_files/Android-build/SDL-android-project/jni/SDL/src/video/android/SDL_androidkeyboard.c
old mode 100755
new mode 100644
diff --git a/project_files/Android-build/Templates/Makefile.android b/project_files/Android-build/Templates/Makefile.android
new file mode 100644
index 0000000..80dc08d
--- /dev/null
+++ b/project_files/Android-build/Templates/Makefile.android
@@ -0,0 +1,41 @@
+SDL_ANDROID_DIR=${CMAKE_CURRENT_SOURCE_DIR}/SDL-android-project
+
+PPCROSSARM=${FPC_DIR}/ppcrossarm
+PPCROSSARM_FLAGS= -Xd -O2 -g -Tlinux -XParm-linux-androideabi- -B -vwnh -n
+PPCROSSARM_INCLUDES= \
+	-FD${ANDROID_NDK_TOOLCHAINDIR}/bin \
+	-Fu${FPC_DIR}/../rtl/units/arm-linux \
+        -Fu${CMAKE_CURRENT_SOURCE_DIR} \
+        -Fi../../hedgewars \
+	-Fl${ANDROID_NDK}/platforms/android-${ANDROID_NDK_API_LVL}/arch-arm/usr/lib \
+	-Fl$(SDL_ANDROID_DIR)/libs/armeabi \
+	-Fl${ANDROID_NDK_TOOLCHAINDIR}/lib/gcc/arm-linux/arm-linux-androideabi/4.4.3/ \
+
+#LINKERFLAGS= -k"--static"
+FPC_DEFINES=-dandroid -darm
+
+all: install/debug
+build:
+	-${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_SOURCE_DIR}/out
+
+	${ANDROID_NDK}/ndk-build -C $(SDL_ANDROID_DIR) -j 8
+
+	$(PPCROSSARM) $(LINKERFLAGS) $(PPCROSSARM_FLAGS) $(PPCROSSARM_INCLUDES) $(FPC_DEFINES) -o${CMAKE_CURRENT_SOURCE_DIR}/out/libhwengine.so ${CMAKE_CURRENT_SOURCE_DIR}/../../hedgewars/hwLibrary.pas
+	${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/out/libhwengine.so $(SDL_ANDROID_DIR)/libs/armeabi/
+
+debug: build
+	${ANT} clean -f $(SDL_ANDROID_DIR)/build.xml
+	${ANT} debug -f $(SDL_ANDROID_DIR)/build.xml
+unsigned: build 
+	${ANT} clean -f $(SDL_ANDROID_DIR)/build.xml
+	${ANT} release -f $(SDL_ANDROID_DIR)/build.xml
+
+install/debug: debug
+	${ANT} installd -f $(SDL_ANDROID_DIR)/build.xml
+install/release: release
+	${ANT} installd -f $(SDL_ANDROID_DIR)/build.xml
+       
+clean:  
+	${CMAKE_COMMAND} -E remove_directory ${CMAKE_CURRENT_SOURCE_DIR}/out
+	${ANDROID_NDK}/ndk-build -C $(SDL_ANDROID_DIR) -j 8 clean
+	${ANT} clean -f $(SDL_ANDROID_DIR)/build.xml
diff --git a/project_files/Android-build/download_libs.sh b/project_files/Android-build/download_libs.sh
new file mode 100644
index 0000000..5d8419a
--- /dev/null
+++ b/project_files/Android-build/download_libs.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+download_and_zip (){
+    echo "Downloading: $1"
+    curl -silent -o tmp.zip $1 #grab the zips from an url
+    unzip -qq tmp.zip  -d SDL-android-project/jni/tmp #unzip it to a tmp file
+    rm -fr SDL-android-project/jni/$2 #remove any old dirs, we will get those files back with hg revert in CMakeList
+    mv SDL-android-project/jni/tmp/* SDL-android-project/jni/$2 #move the tmp dir to the jni directory
+    rm tmp.zip #remove old tmp dir
+}
+download_and_zip http://www.xelification.com/tmp/jpeg.zip jpeg
+download_and_zip http://www.xelification.com/tmp/png.zip png
+download_and_zip http://www.libsdl.org/projects/SDL_image/release/SDL_image-1.2.12.zip SDL_image
+download_and_zip http://www.libsdl.org/projects/SDL_mixer/release/SDL_mixer-1.2.12.zip SDL_mixer
+download_and_zip http://www.xelification.com/tmp/mikmod.zip mikmod #temporary url since the libsdl.org site doesn't work at the moment
+download_and_zip http://www.xelification.com/tmp/SDL_net.zip SDL_net
+download_and_zip http://www.libsdl.org/projects/SDL_ttf/release/SDL_ttf-2.0.11.zip SDL_ttf
+download_and_zip http://www.libsdl.org/tmp/SDL-1.3.zip SDL
+
diff --git a/project_files/AudioMono/Music/Art.ogg b/project_files/AudioMono/Music/Art.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Music/Brick.ogg b/project_files/AudioMono/Music/Brick.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Music/Castle.ogg b/project_files/AudioMono/Music/Castle.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Music/City.ogg b/project_files/AudioMono/Music/City.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Music/Compost.ogg b/project_files/AudioMono/Music/Compost.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Music/Desert.ogg b/project_files/AudioMono/Music/Desert.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Music/EarthRise.ogg b/project_files/AudioMono/Music/EarthRise.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Music/Freeway.ogg b/project_files/AudioMono/Music/Freeway.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Music/Golf.ogg b/project_files/AudioMono/Music/Golf.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Music/Halloween.ogg b/project_files/AudioMono/Music/Halloween.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Music/Nature.ogg b/project_files/AudioMono/Music/Nature.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Music/Olympics.ogg b/project_files/AudioMono/Music/Olympics.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Music/Rock.ogg b/project_files/AudioMono/Music/Rock.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Music/Sheep.ogg b/project_files/AudioMono/Music/Sheep.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Music/bath.ogg b/project_files/AudioMono/Music/bath.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Music/hell.ogg b/project_files/AudioMono/Music/hell.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Music/main_theme.ogg b/project_files/AudioMono/Music/main_theme.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Music/oriental.ogg b/project_files/AudioMono/Music/oriental.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Music/pirate.ogg b/project_files/AudioMono/Music/pirate.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Music/snow.ogg b/project_files/AudioMono/Music/snow.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Music/underwater.ogg b/project_files/AudioMono/Music/underwater.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/1C.ogg b/project_files/AudioMono/Sounds/1C.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/2D.ogg b/project_files/AudioMono/Sounds/2D.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/3E.ogg b/project_files/AudioMono/Sounds/3E.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/4F.ogg b/project_files/AudioMono/Sounds/4F.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/5G.ogg b/project_files/AudioMono/Sounds/5G.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/6A.ogg b/project_files/AudioMono/Sounds/6A.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/7B.ogg b/project_files/AudioMono/Sounds/7B.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/8C.ogg b/project_files/AudioMono/Sounds/8C.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/9D.ogg b/project_files/AudioMono/Sounds/9D.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/BirdyLay.ogg b/project_files/AudioMono/Sounds/BirdyLay.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/CollectCrate.ogg b/project_files/AudioMono/Sounds/CollectCrate.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/Droplet1.ogg b/project_files/AudioMono/Sounds/Droplet1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/Droplet2.ogg b/project_files/AudioMono/Sounds/Droplet2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/Droplet3.ogg b/project_files/AudioMono/Sounds/Droplet3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/Hellish.ogg b/project_files/AudioMono/Sounds/Hellish.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/Whistle.ogg b/project_files/AudioMono/Sounds/Whistle.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/Yoohoo.ogg b/project_files/AudioMono/Sounds/Yoohoo.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/baseballbat.ogg b/project_files/AudioMono/Sounds/baseballbat.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/bee.ogg b/project_files/AudioMono/Sounds/bee.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/beewater.ogg b/project_files/AudioMono/Sounds/beewater.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/bump.ogg b/project_files/AudioMono/Sounds/bump.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/cake2.ogg b/project_files/AudioMono/Sounds/cake2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/denied.ogg b/project_files/AudioMono/Sounds/denied.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/drillgun.ogg b/project_files/AudioMono/Sounds/drillgun.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/egg.ogg b/project_files/AudioMono/Sounds/egg.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/explosion.ogg b/project_files/AudioMono/Sounds/explosion.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/graveimpact.ogg b/project_files/AudioMono/Sounds/graveimpact.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/grenadeimpact.ogg b/project_files/AudioMono/Sounds/grenadeimpact.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/gun.ogg b/project_files/AudioMono/Sounds/gun.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/hammer.ogg b/project_files/AudioMono/Sounds/hammer.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/hell_growl.ogg b/project_files/AudioMono/Sounds/hell_growl.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/hell_ooff.ogg b/project_files/AudioMono/Sounds/hell_ooff.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/hell_ow.ogg b/project_files/AudioMono/Sounds/hell_ow.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/hell_ugh.ogg b/project_files/AudioMono/Sounds/hell_ugh.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/hogchant3.ogg b/project_files/AudioMono/Sounds/hogchant3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/homerun.ogg b/project_files/AudioMono/Sounds/homerun.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/lowgravity.ogg b/project_files/AudioMono/Sounds/lowgravity.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/melonimpact.ogg b/project_files/AudioMono/Sounds/melonimpact.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/mineimpact.ogg b/project_files/AudioMono/Sounds/mineimpact.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/minetick.ogg b/project_files/AudioMono/Sounds/minetick.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/molotov.ogg b/project_files/AudioMono/Sounds/molotov.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/mortar.ogg b/project_files/AudioMono/Sounds/mortar.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/parachute.ogg b/project_files/AudioMono/Sounds/parachute.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/pickhammer.ogg b/project_files/AudioMono/Sounds/pickhammer.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/placed.ogg b/project_files/AudioMono/Sounds/placed.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/plane.ogg b/project_files/AudioMono/Sounds/plane.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/rcplane.ogg b/project_files/AudioMono/Sounds/rcplane.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/ride_of_the_valkyries.ogg b/project_files/AudioMono/Sounds/ride_of_the_valkyries.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/ropeattach.ogg b/project_files/AudioMono/Sounds/ropeattach.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/roperelease.ogg b/project_files/AudioMono/Sounds/roperelease.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/ropeshot.ogg b/project_files/AudioMono/Sounds/ropeshot.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/shotgunfire.ogg b/project_files/AudioMono/Sounds/shotgunfire.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/shotgunreload.ogg b/project_files/AudioMono/Sounds/shotgunreload.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/shutterclick.ogg b/project_files/AudioMono/Sounds/shutterclick.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/sinegun.ogg b/project_files/AudioMono/Sounds/sinegun.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/skip.ogg b/project_files/AudioMono/Sounds/skip.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/sniperreload.ogg b/project_files/AudioMono/Sounds/sniperreload.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/splash.ogg b/project_files/AudioMono/Sounds/splash.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/steam.ogg b/project_files/AudioMono/Sounds/steam.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/steps.ogg b/project_files/AudioMono/Sounds/steps.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/suddendeath.ogg b/project_files/AudioMono/Sounds/suddendeath.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/switchhog.ogg b/project_files/AudioMono/Sounds/switchhog.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/throwpowerup.ogg b/project_files/AudioMono/Sounds/throwpowerup.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/throwrelease.ogg b/project_files/AudioMono/Sounds/throwrelease.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/ufo.ogg b/project_files/AudioMono/Sounds/ufo.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Amazing.ogg b/project_files/AudioMono/Sounds/voices/British/Amazing.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Boring.ogg b/project_files/AudioMono/Sounds/voices/British/Boring.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Brilliant.ogg b/project_files/AudioMono/Sounds/voices/British/Brilliant.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Bugger.ogg b/project_files/AudioMono/Sounds/voices/British/Bugger.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Bungee.ogg b/project_files/AudioMono/Sounds/voices/British/Bungee.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Byebye.ogg b/project_files/AudioMono/Sounds/voices/British/Byebye.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Comeonthen.ogg b/project_files/AudioMono/Sounds/voices/British/Comeonthen.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Coward.ogg b/project_files/AudioMono/Sounds/voices/British/Coward.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Cutitout.ogg b/project_files/AudioMono/Sounds/voices/British/Cutitout.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Drat.ogg b/project_files/AudioMono/Sounds/voices/British/Drat.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Enemydown.ogg b/project_files/AudioMono/Sounds/voices/British/Enemydown.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Excellent.ogg b/project_files/AudioMono/Sounds/voices/British/Excellent.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Fire.ogg b/project_files/AudioMono/Sounds/voices/British/Fire.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Firepunch1.ogg b/project_files/AudioMono/Sounds/voices/British/Firepunch1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Firstblood.ogg b/project_files/AudioMono/Sounds/voices/British/Firstblood.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Flawless.ogg b/project_files/AudioMono/Sounds/voices/British/Flawless.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Gonnagetyou.ogg b/project_files/AudioMono/Sounds/voices/British/Gonnagetyou.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Grenade.ogg b/project_files/AudioMono/Sounds/voices/British/Grenade.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Hello.ogg b/project_files/AudioMono/Sounds/voices/British/Hello.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Hmm.ogg b/project_files/AudioMono/Sounds/voices/British/Hmm.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Hurry.ogg b/project_files/AudioMono/Sounds/voices/British/Hurry.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Illgetyou.ogg b/project_files/AudioMono/Sounds/voices/British/Illgetyou.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Incoming.ogg b/project_files/AudioMono/Sounds/voices/British/Incoming.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Jump1.ogg b/project_files/AudioMono/Sounds/voices/British/Jump1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Jump2.ogg b/project_files/AudioMono/Sounds/voices/British/Jump2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Jump3.ogg b/project_files/AudioMono/Sounds/voices/British/Jump3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Justyouwait.ogg b/project_files/AudioMono/Sounds/voices/British/Justyouwait.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Kamikaze.ogg b/project_files/AudioMono/Sounds/voices/British/Kamikaze.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Laugh.ogg b/project_files/AudioMono/Sounds/voices/British/Laugh.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Leavemealone.ogg b/project_files/AudioMono/Sounds/voices/British/Leavemealone.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Melon.ogg b/project_files/AudioMono/Sounds/voices/British/Melon.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Missed.ogg b/project_files/AudioMono/Sounds/voices/British/Missed.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Nooo.ogg b/project_files/AudioMono/Sounds/voices/British/Nooo.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Nutter.ogg b/project_files/AudioMono/Sounds/voices/British/Nutter.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Ohdear.ogg b/project_files/AudioMono/Sounds/voices/British/Ohdear.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Ooff1.ogg b/project_files/AudioMono/Sounds/voices/British/Ooff1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Ooff2.ogg b/project_files/AudioMono/Sounds/voices/British/Ooff2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Ooff3.ogg b/project_files/AudioMono/Sounds/voices/British/Ooff3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Oops.ogg b/project_files/AudioMono/Sounds/voices/British/Oops.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Ouch.ogg b/project_files/AudioMono/Sounds/voices/British/Ouch.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Ow1.ogg b/project_files/AudioMono/Sounds/voices/British/Ow1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Ow2.ogg b/project_files/AudioMono/Sounds/voices/British/Ow2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Ow3.ogg b/project_files/AudioMono/Sounds/voices/British/Ow3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Ow4.ogg b/project_files/AudioMono/Sounds/voices/British/Ow4.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Perfect.ogg b/project_files/AudioMono/Sounds/voices/British/Perfect.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/PoisonCough.ogg b/project_files/AudioMono/Sounds/voices/British/PoisonCough.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/PoisonMoan.ogg b/project_files/AudioMono/Sounds/voices/British/PoisonMoan.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Reinforcements.ogg b/project_files/AudioMono/Sounds/voices/British/Reinforcements.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Revenge.ogg b/project_files/AudioMono/Sounds/voices/British/Revenge.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Runaway.ogg b/project_files/AudioMono/Sounds/voices/British/Runaway.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Sameteam.ogg b/project_files/AudioMono/Sounds/voices/British/Sameteam.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Solong.ogg b/project_files/AudioMono/Sounds/voices/British/Solong.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Stupid.ogg b/project_files/AudioMono/Sounds/voices/British/Stupid.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Takecover.ogg b/project_files/AudioMono/Sounds/voices/British/Takecover.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Thisoneismine.ogg b/project_files/AudioMono/Sounds/voices/British/Thisoneismine.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Traitor.ogg b/project_files/AudioMono/Sounds/voices/British/Traitor.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Uh-oh.ogg b/project_files/AudioMono/Sounds/voices/British/Uh-oh.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Victory.ogg b/project_files/AudioMono/Sounds/voices/British/Victory.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Watchit.ogg b/project_files/AudioMono/Sounds/voices/British/Watchit.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Watchthis.ogg b/project_files/AudioMono/Sounds/voices/British/Watchthis.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Whatthe.ogg b/project_files/AudioMono/Sounds/voices/British/Whatthe.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Whoopsee.ogg b/project_files/AudioMono/Sounds/voices/British/Whoopsee.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Yessir.ogg b/project_files/AudioMono/Sounds/voices/British/Yessir.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/British/Youllregretthat.ogg b/project_files/AudioMono/Sounds/voices/British/Youllregretthat.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Boring.ogg b/project_files/AudioMono/Sounds/voices/Classic/Boring.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Byebye.ogg b/project_files/AudioMono/Sounds/voices/Classic/Byebye.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Comeonthen.ogg b/project_files/AudioMono/Sounds/voices/Classic/Comeonthen.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Coward.ogg b/project_files/AudioMono/Sounds/voices/Classic/Coward.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Enemydown.ogg b/project_files/AudioMono/Sounds/voices/Classic/Enemydown.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Firstblood.ogg b/project_files/AudioMono/Sounds/voices/Classic/Firstblood.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Flawless.ogg b/project_files/AudioMono/Sounds/voices/Classic/Flawless.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Hello.ogg b/project_files/AudioMono/Sounds/voices/Classic/Hello.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Hurry.ogg b/project_files/AudioMono/Sounds/voices/Classic/Hurry.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Illgetyou.ogg b/project_files/AudioMono/Sounds/voices/Classic/Illgetyou.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Incoming.ogg b/project_files/AudioMono/Sounds/voices/Classic/Incoming.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Jump1.ogg b/project_files/AudioMono/Sounds/voices/Classic/Jump1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Jump2.ogg b/project_files/AudioMono/Sounds/voices/Classic/Jump2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Jump3.ogg b/project_files/AudioMono/Sounds/voices/Classic/Jump3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Kamikaze.ogg b/project_files/AudioMono/Sounds/voices/Classic/Kamikaze.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Laugh.ogg b/project_files/AudioMono/Sounds/voices/Classic/Laugh.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Missed.ogg b/project_files/AudioMono/Sounds/voices/Classic/Missed.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Nooo.ogg b/project_files/AudioMono/Sounds/voices/Classic/Nooo.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Nutter.ogg b/project_files/AudioMono/Sounds/voices/Classic/Nutter.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Ooff1.ogg b/project_files/AudioMono/Sounds/voices/Classic/Ooff1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Ooff2.ogg b/project_files/AudioMono/Sounds/voices/Classic/Ooff2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Ooff3.ogg b/project_files/AudioMono/Sounds/voices/Classic/Ooff3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Oops.ogg b/project_files/AudioMono/Sounds/voices/Classic/Oops.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Ow1.ogg b/project_files/AudioMono/Sounds/voices/Classic/Ow1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Ow2.ogg b/project_files/AudioMono/Sounds/voices/Classic/Ow2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Ow3.ogg b/project_files/AudioMono/Sounds/voices/Classic/Ow3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Ow4.ogg b/project_files/AudioMono/Sounds/voices/Classic/Ow4.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/PoisonCough.ogg b/project_files/AudioMono/Sounds/voices/Classic/PoisonCough.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/PoisonMoan.ogg b/project_files/AudioMono/Sounds/voices/Classic/PoisonMoan.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Reinforcements.ogg b/project_files/AudioMono/Sounds/voices/Classic/Reinforcements.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Sameteam.ogg b/project_files/AudioMono/Sounds/voices/Classic/Sameteam.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Stupid.ogg b/project_files/AudioMono/Sounds/voices/Classic/Stupid.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Takecover.ogg b/project_files/AudioMono/Sounds/voices/Classic/Takecover.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Traitor.ogg b/project_files/AudioMono/Sounds/voices/Classic/Traitor.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Uh-oh.ogg b/project_files/AudioMono/Sounds/voices/Classic/Uh-oh.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Victory.ogg b/project_files/AudioMono/Sounds/voices/Classic/Victory.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Watchit.ogg b/project_files/AudioMono/Sounds/voices/Classic/Watchit.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Yessir.ogg b/project_files/AudioMono/Sounds/voices/Classic/Yessir.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Classic/Youllregretthat.ogg b/project_files/AudioMono/Sounds/voices/Classic/Youllregretthat.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Amazing.ogg b/project_files/AudioMono/Sounds/voices/Default/Amazing.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Boring.ogg b/project_files/AudioMono/Sounds/voices/Default/Boring.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Brilliant.ogg b/project_files/AudioMono/Sounds/voices/Default/Brilliant.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Bugger.ogg b/project_files/AudioMono/Sounds/voices/Default/Bugger.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Bungee.ogg b/project_files/AudioMono/Sounds/voices/Default/Bungee.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Byebye.ogg b/project_files/AudioMono/Sounds/voices/Default/Byebye.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Comeonthen.ogg b/project_files/AudioMono/Sounds/voices/Default/Comeonthen.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Coward.ogg b/project_files/AudioMono/Sounds/voices/Default/Coward.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Cutitout.ogg b/project_files/AudioMono/Sounds/voices/Default/Cutitout.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Drat.ogg b/project_files/AudioMono/Sounds/voices/Default/Drat.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Enemydown.ogg b/project_files/AudioMono/Sounds/voices/Default/Enemydown.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Excellent.ogg b/project_files/AudioMono/Sounds/voices/Default/Excellent.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Fire.ogg b/project_files/AudioMono/Sounds/voices/Default/Fire.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Firepunch1.ogg b/project_files/AudioMono/Sounds/voices/Default/Firepunch1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Firepunch2.ogg b/project_files/AudioMono/Sounds/voices/Default/Firepunch2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Firepunch3.ogg b/project_files/AudioMono/Sounds/voices/Default/Firepunch3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Firepunch4.ogg b/project_files/AudioMono/Sounds/voices/Default/Firepunch4.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Firepunch5.ogg b/project_files/AudioMono/Sounds/voices/Default/Firepunch5.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Firepunch6.ogg b/project_files/AudioMono/Sounds/voices/Default/Firepunch6.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Firstblood.ogg b/project_files/AudioMono/Sounds/voices/Default/Firstblood.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Flawless.ogg b/project_files/AudioMono/Sounds/voices/Default/Flawless.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Gonnagetyou.ogg b/project_files/AudioMono/Sounds/voices/Default/Gonnagetyou.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Grenade.ogg b/project_files/AudioMono/Sounds/voices/Default/Grenade.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Hello.ogg b/project_files/AudioMono/Sounds/voices/Default/Hello.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Hmm.ogg b/project_files/AudioMono/Sounds/voices/Default/Hmm.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Hurry.ogg b/project_files/AudioMono/Sounds/voices/Default/Hurry.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Illgetyou.ogg b/project_files/AudioMono/Sounds/voices/Default/Illgetyou.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Incoming.ogg b/project_files/AudioMono/Sounds/voices/Default/Incoming.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Jump1.ogg b/project_files/AudioMono/Sounds/voices/Default/Jump1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Jump2.ogg b/project_files/AudioMono/Sounds/voices/Default/Jump2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Jump3.ogg b/project_files/AudioMono/Sounds/voices/Default/Jump3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Justyouwait.ogg b/project_files/AudioMono/Sounds/voices/Default/Justyouwait.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Kamikaze.ogg b/project_files/AudioMono/Sounds/voices/Default/Kamikaze.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Laugh.ogg b/project_files/AudioMono/Sounds/voices/Default/Laugh.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Leavemealone.ogg b/project_files/AudioMono/Sounds/voices/Default/Leavemealone.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Melon.ogg b/project_files/AudioMono/Sounds/voices/Default/Melon.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Missed.ogg b/project_files/AudioMono/Sounds/voices/Default/Missed.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Nooo.ogg b/project_files/AudioMono/Sounds/voices/Default/Nooo.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Nutter.ogg b/project_files/AudioMono/Sounds/voices/Default/Nutter.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Ohdear.ogg b/project_files/AudioMono/Sounds/voices/Default/Ohdear.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Ooff1.ogg b/project_files/AudioMono/Sounds/voices/Default/Ooff1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Ooff2.ogg b/project_files/AudioMono/Sounds/voices/Default/Ooff2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Ooff3.ogg b/project_files/AudioMono/Sounds/voices/Default/Ooff3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Oops.ogg b/project_files/AudioMono/Sounds/voices/Default/Oops.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Ouch.ogg b/project_files/AudioMono/Sounds/voices/Default/Ouch.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Ow1.ogg b/project_files/AudioMono/Sounds/voices/Default/Ow1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Ow2.ogg b/project_files/AudioMono/Sounds/voices/Default/Ow2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Ow3.ogg b/project_files/AudioMono/Sounds/voices/Default/Ow3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Ow4.ogg b/project_files/AudioMono/Sounds/voices/Default/Ow4.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Perfect.ogg b/project_files/AudioMono/Sounds/voices/Default/Perfect.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/PoisonCough.ogg b/project_files/AudioMono/Sounds/voices/Default/PoisonCough.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/PoisonMoan.ogg b/project_files/AudioMono/Sounds/voices/Default/PoisonMoan.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Reinforcements.ogg b/project_files/AudioMono/Sounds/voices/Default/Reinforcements.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Revenge.ogg b/project_files/AudioMono/Sounds/voices/Default/Revenge.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Runaway.ogg b/project_files/AudioMono/Sounds/voices/Default/Runaway.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Sameteam.ogg b/project_files/AudioMono/Sounds/voices/Default/Sameteam.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Solong.ogg b/project_files/AudioMono/Sounds/voices/Default/Solong.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Stupid.ogg b/project_files/AudioMono/Sounds/voices/Default/Stupid.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Takecover.ogg b/project_files/AudioMono/Sounds/voices/Default/Takecover.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Thisoneismine.ogg b/project_files/AudioMono/Sounds/voices/Default/Thisoneismine.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Traitor.ogg b/project_files/AudioMono/Sounds/voices/Default/Traitor.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Uh-oh.ogg b/project_files/AudioMono/Sounds/voices/Default/Uh-oh.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Victory.ogg b/project_files/AudioMono/Sounds/voices/Default/Victory.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Watchit.ogg b/project_files/AudioMono/Sounds/voices/Default/Watchit.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Watchthis.ogg b/project_files/AudioMono/Sounds/voices/Default/Watchthis.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Whatthe.ogg b/project_files/AudioMono/Sounds/voices/Default/Whatthe.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Whoopsee.ogg b/project_files/AudioMono/Sounds/voices/Default/Whoopsee.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Yessir.ogg b/project_files/AudioMono/Sounds/voices/Default/Yessir.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Default/Youllregretthat.ogg b/project_files/AudioMono/Sounds/voices/Default/Youllregretthat.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Amazing.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Amazing.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Boring.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Boring.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Brilliant.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Brilliant.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Bugger.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Bugger.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Bungee.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Bungee.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Byebye.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Byebye.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Comeonthen.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Comeonthen.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Coward.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Coward.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Cutitout.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Cutitout.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Drat.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Drat.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Enemydown.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Enemydown.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Excellent.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Excellent.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Fire.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Fire.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Firepunch1.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Firepunch1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Firstblood.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Firstblood.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Flawless.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Flawless.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Gonnagetyou.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Gonnagetyou.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Grenade.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Grenade.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Hello.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Hello.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Hmm.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Hmm.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Hurry.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Hurry.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Illgetyou.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Illgetyou.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Incoming.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Incoming.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Jump1.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Jump1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Jump2.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Jump2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Jump3.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Jump3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Justyouwait.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Justyouwait.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Kamikaze.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Kamikaze.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Laugh.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Laugh.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Leavemealone.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Leavemealone.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Melon.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Melon.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Missed.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Missed.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Nooo.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Nooo.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Nutter.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Nutter.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Ohdear.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Ohdear.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Ooff1.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Ooff1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Ooff2.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Ooff2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Ooff3.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Ooff3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Oops.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Oops.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Ouch.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Ouch.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Ow1.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Ow1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Ow2.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Ow2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Ow3.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Ow3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Ow4.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Ow4.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Perfect.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Perfect.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/PoisonCough.ogg b/project_files/AudioMono/Sounds/voices/Mobster/PoisonCough.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/PoisonMoan.ogg b/project_files/AudioMono/Sounds/voices/Mobster/PoisonMoan.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Reinforcements.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Reinforcements.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Revenge.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Revenge.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Runaway.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Runaway.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Sameteam.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Sameteam.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Solong.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Solong.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Stupid.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Stupid.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Takecover.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Takecover.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Thisoneismine.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Thisoneismine.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Traitor.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Traitor.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Uh-oh.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Uh-oh.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Victory.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Victory.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Watchit.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Watchit.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Watchthis.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Watchthis.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Whatthe.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Whatthe.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Whoopsee.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Whoopsee.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Yessir.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Yessir.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Mobster/Youllregretthat.ogg b/project_files/AudioMono/Sounds/voices/Mobster/Youllregretthat.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Amazing.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Amazing.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Boring.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Boring.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Brilliant.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Brilliant.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Bugger.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Bugger.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Bungee.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Bungee.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Byebye.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Byebye.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Comeonthen.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Comeonthen.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Coward.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Coward.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Cutitout.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Cutitout.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Drat.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Drat.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Enemydown.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Enemydown.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Excellent.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Excellent.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Fire.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Fire.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Firepunch1.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Firepunch1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Firstblood.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Firstblood.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Flawless.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Flawless.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Gonnagetyou.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Gonnagetyou.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Grenade.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Grenade.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Hello.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Hello.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Hmm.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Hmm.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Hurry.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Hurry.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Illgetyou.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Illgetyou.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Incoming.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Incoming.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Jump1.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Jump1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Jump2.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Jump2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Jump3.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Jump3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Justyouwait.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Justyouwait.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Kamikaze.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Kamikaze.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Laugh.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Laugh.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Leavemealone.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Leavemealone.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Melon.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Melon.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Missed.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Missed.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Nooo.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Nooo.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Nutter.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Nutter.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Ohdear.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Ohdear.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Ooff1.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Ooff1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Ooff2.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Ooff2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Ooff3.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Ooff3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Oops.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Oops.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Ouch.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Ouch.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Ow1.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Ow1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Ow2.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Ow2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Ow3.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Ow3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Ow4.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Ow4.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Perfect.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Perfect.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/PoisonCough.ogg b/project_files/AudioMono/Sounds/voices/Pirate/PoisonCough.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/PoisonMoan.ogg b/project_files/AudioMono/Sounds/voices/Pirate/PoisonMoan.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Reinforcements.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Reinforcements.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Revenge.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Revenge.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Runaway.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Runaway.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Sameteam.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Sameteam.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Solong.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Solong.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Stupid.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Stupid.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Takecover.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Takecover.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Thisoneismine.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Thisoneismine.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Traitor.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Traitor.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Uh-oh.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Uh-oh.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Victory.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Victory.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Watchit.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Watchit.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Watchthis.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Watchthis.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Whatthe.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Whatthe.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Whoopsee.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Whoopsee.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Yessir.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Yessir.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Youllregretthat.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Youllregretthat.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Amazing.ogg b/project_files/AudioMono/Sounds/voices/Robot/Amazing.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Boring.ogg b/project_files/AudioMono/Sounds/voices/Robot/Boring.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Brilliant.ogg b/project_files/AudioMono/Sounds/voices/Robot/Brilliant.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Bugger.ogg b/project_files/AudioMono/Sounds/voices/Robot/Bugger.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Bungee.ogg b/project_files/AudioMono/Sounds/voices/Robot/Bungee.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Byebye.ogg b/project_files/AudioMono/Sounds/voices/Robot/Byebye.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Comeonthen.ogg b/project_files/AudioMono/Sounds/voices/Robot/Comeonthen.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Coward.ogg b/project_files/AudioMono/Sounds/voices/Robot/Coward.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Cutitout.ogg b/project_files/AudioMono/Sounds/voices/Robot/Cutitout.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Drat.ogg b/project_files/AudioMono/Sounds/voices/Robot/Drat.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Enemydown.ogg b/project_files/AudioMono/Sounds/voices/Robot/Enemydown.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Excellent.ogg b/project_files/AudioMono/Sounds/voices/Robot/Excellent.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Fire.ogg b/project_files/AudioMono/Sounds/voices/Robot/Fire.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Firepunch1.ogg b/project_files/AudioMono/Sounds/voices/Robot/Firepunch1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Firstblood.ogg b/project_files/AudioMono/Sounds/voices/Robot/Firstblood.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Flawless.ogg b/project_files/AudioMono/Sounds/voices/Robot/Flawless.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Gonnagetyou.ogg b/project_files/AudioMono/Sounds/voices/Robot/Gonnagetyou.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Grenade.ogg b/project_files/AudioMono/Sounds/voices/Robot/Grenade.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Hello.ogg b/project_files/AudioMono/Sounds/voices/Robot/Hello.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Hmm.ogg b/project_files/AudioMono/Sounds/voices/Robot/Hmm.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Hurry.ogg b/project_files/AudioMono/Sounds/voices/Robot/Hurry.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Illgetyou.ogg b/project_files/AudioMono/Sounds/voices/Robot/Illgetyou.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Incoming.ogg b/project_files/AudioMono/Sounds/voices/Robot/Incoming.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Jump1.ogg b/project_files/AudioMono/Sounds/voices/Robot/Jump1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Jump2.ogg b/project_files/AudioMono/Sounds/voices/Robot/Jump2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Jump3.ogg b/project_files/AudioMono/Sounds/voices/Robot/Jump3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Justyouwait.ogg b/project_files/AudioMono/Sounds/voices/Robot/Justyouwait.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Kamikaze.ogg b/project_files/AudioMono/Sounds/voices/Robot/Kamikaze.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Laugh.ogg b/project_files/AudioMono/Sounds/voices/Robot/Laugh.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Leavemealone.ogg b/project_files/AudioMono/Sounds/voices/Robot/Leavemealone.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Melon.ogg b/project_files/AudioMono/Sounds/voices/Robot/Melon.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Missed.ogg b/project_files/AudioMono/Sounds/voices/Robot/Missed.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Nooo.ogg b/project_files/AudioMono/Sounds/voices/Robot/Nooo.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Nutter.ogg b/project_files/AudioMono/Sounds/voices/Robot/Nutter.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Ohdear.ogg b/project_files/AudioMono/Sounds/voices/Robot/Ohdear.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Ooff1.ogg b/project_files/AudioMono/Sounds/voices/Robot/Ooff1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Ooff2.ogg b/project_files/AudioMono/Sounds/voices/Robot/Ooff2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Ooff3.ogg b/project_files/AudioMono/Sounds/voices/Robot/Ooff3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Oops.ogg b/project_files/AudioMono/Sounds/voices/Robot/Oops.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Ouch.ogg b/project_files/AudioMono/Sounds/voices/Robot/Ouch.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Ow1.ogg b/project_files/AudioMono/Sounds/voices/Robot/Ow1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Ow2.ogg b/project_files/AudioMono/Sounds/voices/Robot/Ow2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Ow3.ogg b/project_files/AudioMono/Sounds/voices/Robot/Ow3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Ow4.ogg b/project_files/AudioMono/Sounds/voices/Robot/Ow4.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Perfect.ogg b/project_files/AudioMono/Sounds/voices/Robot/Perfect.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/PoisonCough.ogg b/project_files/AudioMono/Sounds/voices/Robot/PoisonCough.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/PoisonMoan.ogg b/project_files/AudioMono/Sounds/voices/Robot/PoisonMoan.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Reinforcements.ogg b/project_files/AudioMono/Sounds/voices/Robot/Reinforcements.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Revenge.ogg b/project_files/AudioMono/Sounds/voices/Robot/Revenge.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Runaway.ogg b/project_files/AudioMono/Sounds/voices/Robot/Runaway.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Sameteam.ogg b/project_files/AudioMono/Sounds/voices/Robot/Sameteam.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Solong.ogg b/project_files/AudioMono/Sounds/voices/Robot/Solong.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Stupid.ogg b/project_files/AudioMono/Sounds/voices/Robot/Stupid.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Takecover.ogg b/project_files/AudioMono/Sounds/voices/Robot/Takecover.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Thisoneismine.ogg b/project_files/AudioMono/Sounds/voices/Robot/Thisoneismine.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Traitor.ogg b/project_files/AudioMono/Sounds/voices/Robot/Traitor.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Uh-oh.ogg b/project_files/AudioMono/Sounds/voices/Robot/Uh-oh.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Victory.ogg b/project_files/AudioMono/Sounds/voices/Robot/Victory.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Watchit.ogg b/project_files/AudioMono/Sounds/voices/Robot/Watchit.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Watchthis.ogg b/project_files/AudioMono/Sounds/voices/Robot/Watchthis.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Whatthe.ogg b/project_files/AudioMono/Sounds/voices/Robot/Whatthe.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Whoopsee.ogg b/project_files/AudioMono/Sounds/voices/Robot/Whoopsee.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Yessir.ogg b/project_files/AudioMono/Sounds/voices/Robot/Yessir.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Youllregretthat.ogg b/project_files/AudioMono/Sounds/voices/Robot/Youllregretthat.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Amazing.ogg b/project_files/AudioMono/Sounds/voices/Russian/Amazing.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Boring.ogg b/project_files/AudioMono/Sounds/voices/Russian/Boring.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Brilliant.ogg b/project_files/AudioMono/Sounds/voices/Russian/Brilliant.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Bugger.ogg b/project_files/AudioMono/Sounds/voices/Russian/Bugger.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Bungee.ogg b/project_files/AudioMono/Sounds/voices/Russian/Bungee.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Byebye.ogg b/project_files/AudioMono/Sounds/voices/Russian/Byebye.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Comeonthen.ogg b/project_files/AudioMono/Sounds/voices/Russian/Comeonthen.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Coward.ogg b/project_files/AudioMono/Sounds/voices/Russian/Coward.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Cutitout.ogg b/project_files/AudioMono/Sounds/voices/Russian/Cutitout.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Drat.ogg b/project_files/AudioMono/Sounds/voices/Russian/Drat.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Enemydown.ogg b/project_files/AudioMono/Sounds/voices/Russian/Enemydown.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Excellent.ogg b/project_files/AudioMono/Sounds/voices/Russian/Excellent.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Fire.ogg b/project_files/AudioMono/Sounds/voices/Russian/Fire.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Firepunch1.ogg b/project_files/AudioMono/Sounds/voices/Russian/Firepunch1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Firstblood.ogg b/project_files/AudioMono/Sounds/voices/Russian/Firstblood.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Flawless.ogg b/project_files/AudioMono/Sounds/voices/Russian/Flawless.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Gonnagetyou.ogg b/project_files/AudioMono/Sounds/voices/Russian/Gonnagetyou.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Grenade.ogg b/project_files/AudioMono/Sounds/voices/Russian/Grenade.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Hello.ogg b/project_files/AudioMono/Sounds/voices/Russian/Hello.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Hmm.ogg b/project_files/AudioMono/Sounds/voices/Russian/Hmm.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Hurry.ogg b/project_files/AudioMono/Sounds/voices/Russian/Hurry.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Illgetyou.ogg b/project_files/AudioMono/Sounds/voices/Russian/Illgetyou.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Incoming.ogg b/project_files/AudioMono/Sounds/voices/Russian/Incoming.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Jump1.ogg b/project_files/AudioMono/Sounds/voices/Russian/Jump1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Jump2.ogg b/project_files/AudioMono/Sounds/voices/Russian/Jump2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Jump3.ogg b/project_files/AudioMono/Sounds/voices/Russian/Jump3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Justyouwait.ogg b/project_files/AudioMono/Sounds/voices/Russian/Justyouwait.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Kamikaze.ogg b/project_files/AudioMono/Sounds/voices/Russian/Kamikaze.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Laugh.ogg b/project_files/AudioMono/Sounds/voices/Russian/Laugh.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Leavemealone.ogg b/project_files/AudioMono/Sounds/voices/Russian/Leavemealone.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Melon.ogg b/project_files/AudioMono/Sounds/voices/Russian/Melon.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Missed.ogg b/project_files/AudioMono/Sounds/voices/Russian/Missed.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Nooo.ogg b/project_files/AudioMono/Sounds/voices/Russian/Nooo.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Nutter.ogg b/project_files/AudioMono/Sounds/voices/Russian/Nutter.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Ohdear.ogg b/project_files/AudioMono/Sounds/voices/Russian/Ohdear.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Ooff1.ogg b/project_files/AudioMono/Sounds/voices/Russian/Ooff1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Ooff2.ogg b/project_files/AudioMono/Sounds/voices/Russian/Ooff2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Ooff3.ogg b/project_files/AudioMono/Sounds/voices/Russian/Ooff3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Oops.ogg b/project_files/AudioMono/Sounds/voices/Russian/Oops.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Ouch.ogg b/project_files/AudioMono/Sounds/voices/Russian/Ouch.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Ow1.ogg b/project_files/AudioMono/Sounds/voices/Russian/Ow1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Ow2.ogg b/project_files/AudioMono/Sounds/voices/Russian/Ow2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Ow3.ogg b/project_files/AudioMono/Sounds/voices/Russian/Ow3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Ow4.ogg b/project_files/AudioMono/Sounds/voices/Russian/Ow4.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Perfect.ogg b/project_files/AudioMono/Sounds/voices/Russian/Perfect.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/PoisonCough.ogg b/project_files/AudioMono/Sounds/voices/Russian/PoisonCough.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/PoisonMoan.ogg b/project_files/AudioMono/Sounds/voices/Russian/PoisonMoan.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Reinforcements.ogg b/project_files/AudioMono/Sounds/voices/Russian/Reinforcements.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Revenge.ogg b/project_files/AudioMono/Sounds/voices/Russian/Revenge.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Runaway.ogg b/project_files/AudioMono/Sounds/voices/Russian/Runaway.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Sameteam.ogg b/project_files/AudioMono/Sounds/voices/Russian/Sameteam.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Solong.ogg b/project_files/AudioMono/Sounds/voices/Russian/Solong.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Stupid.ogg b/project_files/AudioMono/Sounds/voices/Russian/Stupid.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Takecover.ogg b/project_files/AudioMono/Sounds/voices/Russian/Takecover.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Thisoneismine.ogg b/project_files/AudioMono/Sounds/voices/Russian/Thisoneismine.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Traitor.ogg b/project_files/AudioMono/Sounds/voices/Russian/Traitor.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Uh-oh.ogg b/project_files/AudioMono/Sounds/voices/Russian/Uh-oh.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Victory.ogg b/project_files/AudioMono/Sounds/voices/Russian/Victory.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Watchit.ogg b/project_files/AudioMono/Sounds/voices/Russian/Watchit.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Watchthis.ogg b/project_files/AudioMono/Sounds/voices/Russian/Watchthis.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Whatthe.ogg b/project_files/AudioMono/Sounds/voices/Russian/Whatthe.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Whoopsee.ogg b/project_files/AudioMono/Sounds/voices/Russian/Whoopsee.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Yessir.ogg b/project_files/AudioMono/Sounds/voices/Russian/Yessir.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Russian/Youllregretthat.ogg b/project_files/AudioMono/Sounds/voices/Russian/Youllregretthat.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Amazing.ogg b/project_files/AudioMono/Sounds/voices/Singer/Amazing.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Boring.ogg b/project_files/AudioMono/Sounds/voices/Singer/Boring.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Brilliant.ogg b/project_files/AudioMono/Sounds/voices/Singer/Brilliant.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Bugger.ogg b/project_files/AudioMono/Sounds/voices/Singer/Bugger.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Bungee.ogg b/project_files/AudioMono/Sounds/voices/Singer/Bungee.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Byebye.ogg b/project_files/AudioMono/Sounds/voices/Singer/Byebye.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Comeonthen.ogg b/project_files/AudioMono/Sounds/voices/Singer/Comeonthen.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Coward.ogg b/project_files/AudioMono/Sounds/voices/Singer/Coward.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Cutitout.ogg b/project_files/AudioMono/Sounds/voices/Singer/Cutitout.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Drat.ogg b/project_files/AudioMono/Sounds/voices/Singer/Drat.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Enemydown.ogg b/project_files/AudioMono/Sounds/voices/Singer/Enemydown.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Excellent.ogg b/project_files/AudioMono/Sounds/voices/Singer/Excellent.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Fire.ogg b/project_files/AudioMono/Sounds/voices/Singer/Fire.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Firepunch1.ogg b/project_files/AudioMono/Sounds/voices/Singer/Firepunch1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Firstblood.ogg b/project_files/AudioMono/Sounds/voices/Singer/Firstblood.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Flawless.ogg b/project_files/AudioMono/Sounds/voices/Singer/Flawless.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/FlawlessPossibility.ogg b/project_files/AudioMono/Sounds/voices/Singer/FlawlessPossibility.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Gonnagetyou.ogg b/project_files/AudioMono/Sounds/voices/Singer/Gonnagetyou.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Grenade.ogg b/project_files/AudioMono/Sounds/voices/Singer/Grenade.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Hello.ogg b/project_files/AudioMono/Sounds/voices/Singer/Hello.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Hmm.ogg b/project_files/AudioMono/Sounds/voices/Singer/Hmm.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Hurry.ogg b/project_files/AudioMono/Sounds/voices/Singer/Hurry.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Illgetyou.ogg b/project_files/AudioMono/Sounds/voices/Singer/Illgetyou.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Incoming.ogg b/project_files/AudioMono/Sounds/voices/Singer/Incoming.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Jump1.ogg b/project_files/AudioMono/Sounds/voices/Singer/Jump1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Jump2.ogg b/project_files/AudioMono/Sounds/voices/Singer/Jump2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Jump3.ogg b/project_files/AudioMono/Sounds/voices/Singer/Jump3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Justyouwait.ogg b/project_files/AudioMono/Sounds/voices/Singer/Justyouwait.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Kamikaze.ogg b/project_files/AudioMono/Sounds/voices/Singer/Kamikaze.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Laugh.ogg b/project_files/AudioMono/Sounds/voices/Singer/Laugh.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Leavemealone.ogg b/project_files/AudioMono/Sounds/voices/Singer/Leavemealone.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Melon.ogg b/project_files/AudioMono/Sounds/voices/Singer/Melon.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Missed.ogg b/project_files/AudioMono/Sounds/voices/Singer/Missed.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Nooo.ogg b/project_files/AudioMono/Sounds/voices/Singer/Nooo.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Nutter.ogg b/project_files/AudioMono/Sounds/voices/Singer/Nutter.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Ohdear.ogg b/project_files/AudioMono/Sounds/voices/Singer/Ohdear.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Ooff1.ogg b/project_files/AudioMono/Sounds/voices/Singer/Ooff1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Ooff2.ogg b/project_files/AudioMono/Sounds/voices/Singer/Ooff2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Ooff3.ogg b/project_files/AudioMono/Sounds/voices/Singer/Ooff3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Oops.ogg b/project_files/AudioMono/Sounds/voices/Singer/Oops.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Ouch.ogg b/project_files/AudioMono/Sounds/voices/Singer/Ouch.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Ow1.ogg b/project_files/AudioMono/Sounds/voices/Singer/Ow1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Ow2.ogg b/project_files/AudioMono/Sounds/voices/Singer/Ow2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Ow3.ogg b/project_files/AudioMono/Sounds/voices/Singer/Ow3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Ow4.ogg b/project_files/AudioMono/Sounds/voices/Singer/Ow4.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Perfect.ogg b/project_files/AudioMono/Sounds/voices/Singer/Perfect.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/PoisonCough.ogg b/project_files/AudioMono/Sounds/voices/Singer/PoisonCough.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/PoisonMoan.ogg b/project_files/AudioMono/Sounds/voices/Singer/PoisonMoan.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Reinforcements.ogg b/project_files/AudioMono/Sounds/voices/Singer/Reinforcements.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Revenge.ogg b/project_files/AudioMono/Sounds/voices/Singer/Revenge.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Runaway.ogg b/project_files/AudioMono/Sounds/voices/Singer/Runaway.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Sameteam.ogg b/project_files/AudioMono/Sounds/voices/Singer/Sameteam.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Solong.ogg b/project_files/AudioMono/Sounds/voices/Singer/Solong.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Stupid.ogg b/project_files/AudioMono/Sounds/voices/Singer/Stupid.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Takecover.ogg b/project_files/AudioMono/Sounds/voices/Singer/Takecover.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Thisoneismine.ogg b/project_files/AudioMono/Sounds/voices/Singer/Thisoneismine.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Traitor.ogg b/project_files/AudioMono/Sounds/voices/Singer/Traitor.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Uh-oh.ogg b/project_files/AudioMono/Sounds/voices/Singer/Uh-oh.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Victory.ogg b/project_files/AudioMono/Sounds/voices/Singer/Victory.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/VictoryPossibility.ogg b/project_files/AudioMono/Sounds/voices/Singer/VictoryPossibility.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Watchit.ogg b/project_files/AudioMono/Sounds/voices/Singer/Watchit.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Watchthis.ogg b/project_files/AudioMono/Sounds/voices/Singer/Watchthis.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Whatthe.ogg b/project_files/AudioMono/Sounds/voices/Singer/Whatthe.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Whoopsee.ogg b/project_files/AudioMono/Sounds/voices/Singer/Whoopsee.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Yessir.ogg b/project_files/AudioMono/Sounds/voices/Singer/Yessir.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Youllregretthat.ogg b/project_files/AudioMono/Sounds/voices/Singer/Youllregretthat.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Amazing.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Amazing.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Boring.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Boring.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Brilliant.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Brilliant.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Bugger.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Bugger.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Bungee.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Bungee.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Byebye.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Byebye.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Comeonthen.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Comeonthen.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Coward.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Coward.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Cutitout.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Cutitout.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Drat.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Drat.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Enemydown.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Enemydown.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Excellent.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Excellent.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Fire.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Fire.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Firepunch1.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Firepunch1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Firstblood.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Firstblood.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Flawless.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Flawless.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Gonnagetyou.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Gonnagetyou.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Grenade.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Grenade.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Hello.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Hello.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Hmm.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Hmm.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Hurry.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Hurry.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Illgetyou.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Illgetyou.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Incoming.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Incoming.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Jump1.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Jump1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Jump2.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Jump2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Jump3.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Jump3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Justyouwait.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Justyouwait.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Kamikaze.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Kamikaze.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Laugh.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Laugh.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Leavemealone.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Leavemealone.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Melon.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Melon.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Missed.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Missed.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Nooo.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Nooo.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Nutter.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Nutter.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Ohdear.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Ohdear.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Ooff1.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Ooff1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Ooff2.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Ooff2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Ooff3.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Ooff3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Oops.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Oops.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Ouch.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Ouch.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Ow1.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Ow1.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Ow2.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Ow2.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Ow3.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Ow3.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Ow4.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Ow4.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Perfect.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Perfect.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/PoisonCough.ogg b/project_files/AudioMono/Sounds/voices/Surfer/PoisonCough.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/PoisonMoan.ogg b/project_files/AudioMono/Sounds/voices/Surfer/PoisonMoan.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Reinforcements.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Reinforcements.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Revenge.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Revenge.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Runaway.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Runaway.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Sameteam.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Sameteam.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Solong.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Solong.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Stupid.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Stupid.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Takecover.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Takecover.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Thisoneismine.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Thisoneismine.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Traitor.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Traitor.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Uh-oh.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Uh-oh.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Victory.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Victory.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Watchit.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Watchit.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Watchthis.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Watchthis.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Whatthe.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Whatthe.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Whoopsee.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Whoopsee.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Yessir.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Yessir.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Youllregretthat.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Youllregretthat.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/warp.ogg b/project_files/AudioMono/Sounds/warp.ogg
old mode 100755
new mode 100644
diff --git a/project_files/AudioMono/Sounds/whipcrack.ogg b/project_files/AudioMono/Sounds/whipcrack.ogg
old mode 100755
new mode 100644
diff --git a/project_files/HedgewarsMobile/Classes/MGSplitViewController/LICENCE.rtf b/project_files/HedgewarsMobile/Classes/MGSplitViewController/LICENCE.rtf
old mode 100755
new mode 100644
diff --git a/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitCornersView.h b/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitCornersView.h
old mode 100755
new mode 100644
diff --git a/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitCornersView.m b/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitCornersView.m
old mode 100755
new mode 100644
diff --git a/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitDividerView.h b/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitDividerView.h
old mode 100755
new mode 100644
diff --git a/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitDividerView.m b/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitDividerView.m
old mode 100755
new mode 100644
diff --git a/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitViewController.h b/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitViewController.h
old mode 100755
new mode 100644
diff --git a/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitViewController.m b/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitViewController.m
old mode 100755
new mode 100644
diff --git a/project_files/HedgewarsMobile/Classes/MNEValueTrackingSlider.h b/project_files/HedgewarsMobile/Classes/MNEValueTrackingSlider.h
old mode 100755
new mode 100644
diff --git a/project_files/HedgewarsMobile/Classes/MNEValueTrackingSlider.m b/project_files/HedgewarsMobile/Classes/MNEValueTrackingSlider.m
old mode 100755
new mode 100644
diff --git a/project_files/cmdlineClient/cmdlineClient.c b/project_files/cmdlineClient/cmdlineClient.c
new file mode 100644
index 0000000..17f824c
--- /dev/null
+++ b/project_files/cmdlineClient/cmdlineClient.c
@@ -0,0 +1,475 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include <frontlib.h>
+#include <util/logging.h>
+#include <util/util.h>
+#include <base64/base64.h>
+#include <model/schemelist.h>
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <assert.h>
+#include <string.h>
+#include <conio.h>
+#include <windows.h>
+
+#define ENGINE_DIR ".\\"
+#define CONFIG_DIR "..\\share\\hedgewars"
+#define DATA_DIR CONFIG_DIR"\\Data"
+
+static flib_netconn *netconn;
+static flib_gameconn *gameconn;
+static flib_mapconn *mapconn;
+static char nickname[128];
+static flib_metascheme *metacfg;
+static bool netConnected = false;
+
+// Callback function that will be called when the map is rendered
+static void handleMapGenerated(void *context, const uint8_t *bitmap, int numHedgehogs) {
+	printf("Drawing map for %i brave little hogs...", numHedgehogs);
+
+	// Draw the map as ASCII art
+	for(int y=0; y<MAPIMAGE_HEIGHT; y+=8) {
+		for(int x=0; x<MAPIMAGE_WIDTH; x+=6) {
+			int pixelnum = x + y*MAPIMAGE_WIDTH;
+			bool pixel = bitmap[pixelnum>>3] & (1<<(7-(pixelnum&7)));
+			printf(pixel ? "#" : " ");
+		}
+		printf("\n");
+	}
+
+	flib_mapconn_destroy(mapconn);
+	mapconn = NULL;
+}
+
+static void onGameDisconnect(void *context, int reason) {
+	flib_log_i("Connection closed. Reason: %i", reason);
+	flib_gameconn_destroy(gameconn);
+	gameconn = NULL;
+	if(netconn) {
+		flib_netconn_send_roundfinished(netconn, reason==GAME_END_FINISHED);
+	}
+}
+
+// Callback function that will be called on error
+static void handleMapFailure(void *context, const char *errormessage) {
+	flib_log_e("Map rendering failed: %s", errormessage);
+	flib_mapconn_destroy(mapconn);
+	mapconn = NULL;
+}
+
+static void startEngineMap(int port) {
+	char cmdbuffer[255];
+	char argbuffer[255];
+	snprintf(cmdbuffer, 255, "%shwengine.exe", ENGINE_DIR);
+	snprintf(argbuffer, 255, "%s %i landpreview", CONFIG_DIR, port);
+	ShellExecute(NULL, NULL, cmdbuffer, argbuffer, NULL, SW_HIDE);
+}
+
+static void startEngineGame(int port) {
+	char cmdbuffer[255];
+	char argbuffer[255];
+	char base64PlayerName[255];
+	base64_encode(nickname, strlen(nickname), base64PlayerName, sizeof(base64PlayerName));
+	snprintf(cmdbuffer, 255, "%shwengine.exe", ENGINE_DIR);
+	snprintf(argbuffer, 255, "%s 1024 768 32 %i 0 0 0 10 10 %s 0 0 %s 0 0 en.txt", CONFIG_DIR, port, DATA_DIR, base64PlayerName);
+	ShellExecute(NULL, NULL, cmdbuffer, argbuffer, NULL, SW_HIDE);
+}
+
+void handleNetDisconnect(void *context, int reason, const char *message) {
+	printf("Disconnected: %s", message);
+	flib_netconn_destroy(netconn);
+	netconn = NULL;
+}
+
+/*void printRoomList() {
+	const flib_roomlist *roomlist = flib_netconn_get_roomlist(netconn);
+	if(roomlist) {
+		if(roomlist->roomCount>0) {
+			for(int i=0; i<roomlist->roomCount; i++) {
+				if(i>0) {
+					printf(", ");
+				}
+				flib_room *room = roomlist->rooms[i];
+				printf("%s", room->name);
+			}
+		} else {
+			puts("Unfortunately, there are no rooms at the moment.");
+		}
+	} else {
+		puts("Sorry, due to an error the room list is not available.");
+	}
+	puts("\n");
+}*/
+
+void printTeamList() {
+	flib_gamesetup *setup = flib_netconn_create_gamesetup(netconn);
+	if(setup) {
+		puts("The following teams are in this room:");
+		for(int i=0; i<setup->teamlist->teamCount; i++) {
+			if(i>0) {
+				printf(", ");
+			}
+			printf("%s", setup->teamlist->teams[i]->name);
+		}
+		puts("\n");
+	} else {
+		puts("Sorry, due to an error the team list is not available.");
+	}
+	flib_gamesetup_destroy(setup);
+}
+
+void handleNetConnected(void *context) {
+	printf("You enter the lobby of a strange house inhabited by hedgehogs. Looking around, you see hallways branching off to these rooms:\n");
+	//printRoomList();
+	printf("\n\nNow, you can chat by just entering text, or join a room with /join <roomname>.");
+	printf(" You can also /quit or let me /describe <roomname>. Once in a room, you can /add <teamname> and set yourself /ready. You can also /list the available rooms (in the lobby) or the teams (in a room).\n");
+	netConnected = true;
+}
+
+void handleChat(void *context, const char *nick, const char *msg) {
+	if(gameconn) {
+		flib_gameconn_send_chatmsg(gameconn, nick, msg);
+	}
+	printf("%s: %s\n", nick, msg);
+}
+
+void handleEnterRoom(void *context, bool isChief) {
+	puts("You have entered the room.");
+}
+
+void handleRoomJoin(void *context, const char *nick) {
+	if(strcmp(nick, nickname)) {
+		printf("%s is here.\n", nick);
+	}
+}
+
+void handleRoomLeave(void *context, const char *nick, const char *partmsg) {
+	if(strcmp(nick, nickname)) {
+		printf("%s leaves.\n", nick);
+	}
+}
+
+void handleReady(void *context, const char *nick, bool ready) {
+	if(strcmp(nick, nickname)) {
+		if(ready) {
+			printf("%s is ready to go.\n", nick);
+		} else {
+			printf("%s is not ready.\n", nick);
+		}
+	} else {
+		if(ready) {
+			printf("You are ready to go.\n");
+		} else {
+			printf("You are not ready.\n");
+		}
+	}
+}
+
+void handleEmFromNet(void *context, const uint8_t *em, size_t size) {
+	if(gameconn) {
+		flib_gameconn_send_enginemsg(gameconn, em, size);
+	}
+}
+
+void handleEmFromEngine(void *context, const uint8_t *em, size_t size) {
+	if(netconn) {
+		flib_netconn_send_engineMessage(netconn, em, size);
+	}
+}
+
+void handleChatFromGame(void *context, const char *message, bool teamchat) {
+	if(netconn) {
+		if(teamchat) {
+			flib_netconn_send_teamchat(netconn, message);
+		} else {
+			flib_netconn_send_chat(netconn, message);
+		}
+	}
+}
+
+void handleRunGame(void *context) {
+	flib_gamesetup *gamesetup = flib_netconn_create_gamesetup(netconn);
+	if(gameconn) {
+		flib_log_e("Request to start game, but a game is already running.");
+	} else if(gamesetup) {
+		gameconn = flib_gameconn_create(nickname, gamesetup, true);
+		flib_gameconn_onEngineMessage(gameconn, handleEmFromEngine, NULL);
+		flib_gameconn_onDisconnect(gameconn, onGameDisconnect, NULL);
+		flib_gameconn_onChat(gameconn, handleChatFromGame, NULL);
+		startEngineGame(flib_gameconn_getport(gameconn));
+	}
+	flib_gamesetup_destroy(gamesetup);
+}
+
+void handleNickTaken(void *context, const char *nick) {
+	printf("The nickname %s is already in use, please choose a different one:\n", nick);
+	flib_gets(nickname, sizeof(nickname));
+	flib_netconn_send_nick(netconn, nickname);
+}
+
+void handlePwRequest(void *context, const char *nick) {
+	printf("A password is required to log in as %s, please enter (warning: shown in cleartext):\n", nick);
+	char password[256];
+	flib_gets(password, sizeof(password));
+	flib_netconn_send_password(netconn, password);
+}
+
+void handleMessage(void *context, int type, const char *msg) {
+	if(gameconn) {
+		flib_gameconn_send_textmsg(gameconn, 1, msg);
+	}
+	printf("*** %s\n", msg);
+}
+
+void handleTeamAccepted(void *context, const char *teamname) {
+	printf("The team %s has been accepted.\n", teamname);
+}
+
+void handleMapChanged(void *context, const flib_map *map, int changetype) {
+	if(map->mapgen != MAPGEN_NAMED && changetype != NETCONN_MAPCHANGE_THEME) {
+		if(mapconn) {
+			flib_mapconn_destroy(mapconn);
+			mapconn = NULL;
+		}
+		mapconn = flib_mapconn_create(map);
+		if(mapconn) {
+			flib_mapconn_onSuccess(mapconn, handleMapGenerated, NULL);
+			flib_mapconn_onFailure(mapconn, handleMapFailure, NULL);
+			startEngineMap(flib_mapconn_getport(mapconn));
+		}
+	} else if(map->mapgen == MAPGEN_NAMED) {
+		printf("The map %s has been selected.\n", map->name);
+	}
+}
+
+void handleLeaveRoom(void *context, int reason, const char *msg) {
+	if(reason == NETCONN_ROOMLEAVE_ABANDONED) {
+		printf("The chief has abandoned the room.");
+	} else if(reason == NETCONN_ROOMLEAVE_KICKED) {
+		printf("You have been kicked from the room.");
+	}
+	if(msg) {
+		printf(" (%s)", msg);
+	}
+	puts(" You are back in the lobby.");
+}
+
+void handleSchemeChanged(void *context, const flib_scheme *scheme) {
+	printf("Game scheme: %s.\n", scheme->name);
+}
+
+void handleWeaponsetChanged(void *context, const flib_weaponset *weaponset) {
+	printf("Weaponset: %s.\n", weaponset->name);
+}
+
+void handleHogcountChanged(void *context, const char *team, int count) {
+	printf("Team %s will send %i hogs into the fight.\n", team, count);
+}
+
+void handleRoomAdd(void *context, const flib_room *room) {
+	printf("%s created a new room called %s.\n", room->owner, room->name);
+}
+
+void handleRoomDelete(void *context, const char *roomName) {
+	printf("The room %s has collapsed.\n", roomName);
+}
+
+void handleScriptChanged(void *context, const char *script) {
+	printf("Game Type: %s\n", script);
+}
+
+void handleTeamAdd(void *context, const flib_team *team) {
+	printf("%s puts the team %s to the planning board.\n", team->ownerName, team->name);
+}
+
+void handleTeamDelete(void *context, const char *teamName) {
+	printf("The team %s decided not to fight this battle after all.\n", teamName);
+}
+
+void handleTeamColorChanged(void *context, const char *name, int colorIndex) {
+	static const char* colorNames[] = {"red", "blue", "teal", "purple", "pink", "green", "orange", "brown", "yellow"};
+	const char *colorName = "strange";
+	if(colorIndex>=0 && colorIndex < 9) {
+		colorName = colorNames[colorIndex];
+	}
+	printf("The team %s will wear %s uniforms today.\n", name, colorName);
+}
+
+void tick() {
+	if(gameconn) {
+		flib_gameconn_tick(gameconn);
+	}
+	if(netconn) {
+		flib_netconn_tick(netconn);
+	}
+	if(mapconn) {
+		flib_mapconn_tick(mapconn);
+	}
+}
+
+static HANDLE hStdin;
+
+static int init() {
+	hStdin = GetStdHandle(STD_INPUT_HANDLE);
+	if(hStdin == INVALID_HANDLE_VALUE) {
+		flib_log_e("Unable to get stdin handle");
+		return 1;
+	}
+	if(!flib_init(0)) {
+		flib_log_setLevel(FLIB_LOGLEVEL_WARNING);
+		freopen( "CON", "w", stdout );
+		freopen( "CON", "w", stderr );
+		metacfg = flib_metascheme_from_ini("metasettings.ini");
+		if(!metacfg) {
+			flib_quit();
+			return -1;
+		} else {
+			return 0;
+		}
+	}
+	return -1;
+}
+
+int main(int argc, char *argv[]) {
+	if(init()) {
+		return -1;
+	}
+
+	puts("Please enter a nickname:");
+	flib_gets(nickname, sizeof(nickname));
+
+	netconn = flib_netconn_create(nickname, metacfg, DATA_DIR"\\", "140.247.62.101", 46631);
+	if(!netconn) {
+		flib_quit();
+		return -1;
+	}
+
+	flib_netconn_onConnected(netconn, handleNetConnected, NULL);
+	flib_netconn_onDisconnected(netconn, handleNetDisconnect, NULL);
+	flib_netconn_onChat(netconn, handleChat, NULL);
+	flib_netconn_onEnterRoom(netconn, handleEnterRoom, NULL);
+	flib_netconn_onRunGame(netconn, handleRunGame, NULL);
+	flib_netconn_onEngineMessage(netconn, handleEmFromNet, NULL);
+	flib_netconn_onRoomJoin(netconn, handleRoomJoin, NULL);
+	flib_netconn_onRoomLeave(netconn, handleRoomLeave, NULL);
+	flib_netconn_onReadyState(netconn, handleReady, NULL);
+	flib_netconn_onNickTaken(netconn, handleNickTaken, NULL);
+	flib_netconn_onPasswordRequest(netconn, handlePwRequest, NULL);
+	flib_netconn_onMessage(netconn, handleMessage, NULL);
+	flib_netconn_onTeamAccepted(netconn, handleTeamAccepted, NULL);
+	flib_netconn_onMapChanged(netconn, handleMapChanged, NULL);
+	flib_netconn_onLeaveRoom(netconn, handleLeaveRoom, NULL);
+	flib_netconn_onCfgScheme(netconn, handleSchemeChanged, NULL);
+	flib_netconn_onWeaponsetChanged(netconn, handleWeaponsetChanged, NULL);
+	flib_netconn_onHogCountChanged(netconn, handleHogcountChanged, NULL);
+	flib_netconn_onRoomAdd(netconn, handleRoomAdd, NULL);
+	flib_netconn_onRoomDelete(netconn, handleRoomDelete, NULL);
+	flib_netconn_onScriptChanged(netconn, handleScriptChanged, NULL);
+	flib_netconn_onTeamAdd(netconn, handleTeamAdd, NULL);
+	flib_netconn_onTeamDelete(netconn, handleTeamDelete, NULL);
+	flib_netconn_onTeamColorChanged(netconn, handleTeamColorChanged, NULL);
+
+	INPUT_RECORD inputRecord;
+	DWORD eventCount = 0;
+
+	while(netconn || gameconn) {
+		tick();
+		if(netconn && netConnected) {
+			while(PeekConsoleInput(hStdin, &inputRecord, 1, &eventCount) && eventCount>0) {
+				if(inputRecord.EventType != KEY_EVENT) {
+					ReadConsoleInput(hStdin, &inputRecord, 1, &eventCount);
+				} else {
+					printf("%s: ", nickname);
+					char input[256];
+					if(!flib_gets(input, sizeof(input))) {
+						if(!memcmp("/quit", input, strlen("/quit"))) {
+							flib_netconn_send_quit(netconn, "Player quit.");
+						} else if(!memcmp("/describe ", input, strlen("/describe "))) {
+							const char *roomname = input+strlen("/describe ");
+							/*const flib_roomlist *roomlist = flib_netconn_get_roomlist(netconn);
+							flib_room *room = flib_roomlist_find(roomlist, roomname);
+							if(!room) {
+								puts("Unknown room.");
+							} else {
+								char *text = flib_asprintf(
+										"%s is a room created by %s, where %i players (%i teams) are %s on %s%s, using the %s scheme and %s weaponset.",
+										room->name,
+										room->owner,
+										room->playerCount,
+										room->teamCount,
+										room->inProgress ? "fighting" : "preparing to fight",
+										room->map[0]=='+' ? "" : "the map ",
+										!strcmp("+rnd+", room->map) ? "a random map" :
+												!strcmp("+maze+", room->map) ? "a random maze" :
+												!strcmp("+drawn+", room->map) ? "a hand-drawn map" :
+												room->map,
+										room->scheme,
+										room->weapons);
+								if(text) {
+									puts(text);
+								}
+								free(text);
+							}*/
+						} else if(!memcmp("/join ", input, strlen("/join "))) {
+							const char *roomname = input+strlen("/join ");
+							flib_netconn_send_joinRoom(netconn, roomname);
+						} else if(!memcmp("/ready", input, strlen("/ready"))) {
+							flib_netconn_send_toggleReady(netconn);
+						} else if(!memcmp("/loglevel ", input, strlen("/loglevel "))) {
+							int loglevel = atoi(input+strlen("/loglevel "));
+							flib_log_setLevel(loglevel);
+						} else if(!memcmp("/list", input, strlen("/list"))) {
+							if(flib_netconn_is_in_room_context(netconn)) {
+								printTeamList();
+							} else {
+								puts("From this big and expansive lobby, hallways branch off to these rooms:");
+								//printRoomList();
+							}
+						} else if(!memcmp("/addteam ", input, strlen("/addteam "))) {
+							const char *teamname = input+strlen("/addteam ");
+							if(!flib_contains_dir_separator(teamname)) {
+								char *teamfilename = flib_asprintf("%s.hwt", teamname);
+								if(teamfilename) {
+									flib_team *team = flib_team_from_ini(teamfilename);
+									if(team) {
+										flib_netconn_send_addTeam(netconn, team);
+									} else {
+										printf("Teamfile %s not found.\n", teamfilename);
+									}
+									flib_team_destroy(team);
+								}
+								free(teamfilename);
+							}
+						} else if(strlen(input)>0) {
+							flib_netconn_send_chat(netconn, input);
+						}
+					}
+				}
+			}
+		}
+		fflush(stdout);
+		Sleep(10);
+	}
+
+
+	flib_metascheme_release(metacfg);
+	return 0;
+}
diff --git a/project_files/frontlib/Android.mk b/project_files/frontlib/Android.mk
new file mode 100644
index 0000000..945b553
--- /dev/null
+++ b/project_files/frontlib/Android.mk
@@ -0,0 +1,22 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := frontlib
+
+LOCAL_CFLAGS := -I$(LOCAL_PATH)/../Android-build/SDL-android-project/jni/SDL_net -std=c99 -I$(LOCAL_PATH)/../Android-build/SDL-android-project/jni/SDL/include  
+
+LOCAL_SRC_FILES := base64/base64.c iniparser/iniparser.c \
+	iniparser/dictionary.c ipc/gameconn.c ipc/ipcbase.c \
+	ipc/ipcprotocol.c ipc/mapconn.c md5/md5.c model/scheme.c \
+	model/gamesetup.c model/map.c model/mapcfg.c model/room.c \
+	model/schemelist.c model/team.c model/teamlist.c model/weapon.c \
+	net/netbase.c net/netconn_callbacks.c net/netconn_send.c \
+	net/netconn.c net/netprotocol.c util/buffer.c util/inihelper.c \
+	util/logging.c util/util.c frontlib.c hwconsts.c socket.c \
+	extra/jnacontrol.c
+
+LOCAL_SHARED_LIBRARIES += SDL SDL_net
+LOCAL_LDLIBS += -lz
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/project_files/frontlib/CMakeLists.txt b/project_files/frontlib/CMakeLists.txt
new file mode 100644
index 0000000..9886cb5
--- /dev/null
+++ b/project_files/frontlib/CMakeLists.txt
@@ -0,0 +1,21 @@
+find_package(SDL REQUIRED)
+find_package(SDL_net REQUIRED)
+find_package(ZLIB REQUIRED)
+
+add_definitions("-std=c99")
+
+file(GLOB frontlib_src
+        *.c *.h
+        base64/*.c base64/*.h
+        ipc/*.c ipc/*.h
+        md5/*.c md5/*.h
+        model/*.c model/*.h
+        net/*.c net/*.h
+        util/*.c util/*.h
+    )
+
+include_directories(${SDL_INCLUDE_DIR})
+include_directories(${SDLNET_INCLUDE_DIR})
+include_directories(${ZLIB_INCLUDE_DIR})
+
+add_library(frontlib STATIC ${frontlib_src})
diff --git a/project_files/frontlib/base64/base64.c b/project_files/frontlib/base64/base64.c
new file mode 100644
index 0000000..fbd12e1
--- /dev/null
+++ b/project_files/frontlib/base64/base64.c
@@ -0,0 +1,572 @@
+/* base64.c -- Encode binary data using printable characters.
+   Copyright (C) 1999-2001, 2004-2006, 2009-2012 Free Software Foundation, Inc.
+
+   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; either version 2, or (at your option)
+   any later version.
+
+   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, see <http://www.gnu.org/licenses/>.  */
+
+/* Written by Simon Josefsson.  Partially adapted from GNU MailUtils
+ * (mailbox/filter_trans.c, as of 2004-11-28).  Improved by review
+ * from Paul Eggert, Bruno Haible, and Stepan Kasal.
+ *
+ * See also RFC 4648 <http://www.ietf.org/rfc/rfc4648.txt>.
+ *
+ * Be careful with error checking.  Here is how you would typically
+ * use these functions:
+ *
+ * bool ok = base64_decode_alloc (in, inlen, &out, &outlen);
+ * if (!ok)
+ *   FAIL: input was not valid base64
+ * if (out == NULL)
+ *   FAIL: memory allocation error
+ * OK: data in OUT/OUTLEN
+ *
+ * size_t outlen = base64_encode_alloc (in, inlen, &out);
+ * if (out == NULL && outlen == 0 && inlen != 0)
+ *   FAIL: input too long
+ * if (out == NULL)
+ *   FAIL: memory allocation error
+ * OK: data in OUT/OUTLEN.
+ *
+ */
+
+/* Get prototype. */
+#include "base64.h"
+
+/* Get malloc. */
+#include <stdlib.h>
+
+/* Get UCHAR_MAX. */
+#include <limits.h>
+
+#include <string.h>
+
+/* C89 compliant way to cast 'char' to 'unsigned char'. */
+static inline unsigned char
+to_uchar (char ch)
+{
+  return ch;
+}
+
+/* Base64 encode IN array of size INLEN into OUT array of size OUTLEN.
+   If OUTLEN is less than BASE64_LENGTH(INLEN), write as many bytes as
+   possible.  If OUTLEN is larger than BASE64_LENGTH(INLEN), also zero
+   terminate the output buffer. */
+void
+base64_encode (const char *restrict in, size_t inlen,
+               char *restrict out, size_t outlen)
+{
+  static const char b64str[64] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+  while (inlen && outlen)
+    {
+      *out++ = b64str[(to_uchar (in[0]) >> 2) & 0x3f];
+      if (!--outlen)
+        break;
+      *out++ = b64str[((to_uchar (in[0]) << 4)
+                       + (--inlen ? to_uchar (in[1]) >> 4 : 0))
+                      & 0x3f];
+      if (!--outlen)
+        break;
+      *out++ =
+        (inlen
+         ? b64str[((to_uchar (in[1]) << 2)
+                   + (--inlen ? to_uchar (in[2]) >> 6 : 0))
+                  & 0x3f]
+         : '=');
+      if (!--outlen)
+        break;
+      *out++ = inlen ? b64str[to_uchar (in[2]) & 0x3f] : '=';
+      if (!--outlen)
+        break;
+      if (inlen)
+        inlen--;
+      if (inlen)
+        in += 3;
+    }
+
+  if (outlen)
+    *out = '\0';
+}
+
+/* Allocate a buffer and store zero terminated base64 encoded data
+   from array IN of size INLEN, returning BASE64_LENGTH(INLEN), i.e.,
+   the length of the encoded data, excluding the terminating zero.  On
+   return, the OUT variable will hold a pointer to newly allocated
+   memory that must be deallocated by the caller.  If output string
+   length would overflow, 0 is returned and OUT is set to NULL.  If
+   memory allocation failed, OUT is set to NULL, and the return value
+   indicates length of the requested memory block, i.e.,
+   BASE64_LENGTH(inlen) + 1. */
+size_t
+base64_encode_alloc (const char *in, size_t inlen, char **out)
+{
+  size_t outlen = 1 + BASE64_LENGTH (inlen);
+
+  /* Check for overflow in outlen computation.
+   *
+   * If there is no overflow, outlen >= inlen.
+   *
+   * If the operation (inlen + 2) overflows then it yields at most +1, so
+   * outlen is 0.
+   *
+   * If the multiplication overflows, we lose at least half of the
+   * correct value, so the result is < ((inlen + 2) / 3) * 2, which is
+   * less than (inlen + 2) * 0.66667, which is less than inlen as soon as
+   * (inlen > 4).
+   */
+  if (inlen > outlen)
+    {
+      *out = NULL;
+      return 0;
+    }
+
+  *out = malloc (outlen);
+  if (!*out)
+    return outlen;
+
+  base64_encode (in, inlen, *out, outlen);
+
+  return outlen - 1;
+}
+
+/* With this approach this file works independent of the charset used
+   (think EBCDIC).  However, it does assume that the characters in the
+   Base64 alphabet (A-Za-z0-9+/) are encoded in 0..255.  POSIX
+   1003.1-2001 require that char and unsigned char are 8-bit
+   quantities, though, taking care of that problem.  But this may be a
+   potential problem on non-POSIX C99 platforms.
+
+   IBM C V6 for AIX mishandles "#define B64(x) ...'x'...", so use "_"
+   as the formal parameter rather than "x".  */
+#define B64(_)                                  \
+  ((_) == 'A' ? 0                               \
+   : (_) == 'B' ? 1                             \
+   : (_) == 'C' ? 2                             \
+   : (_) == 'D' ? 3                             \
+   : (_) == 'E' ? 4                             \
+   : (_) == 'F' ? 5                             \
+   : (_) == 'G' ? 6                             \
+   : (_) == 'H' ? 7                             \
+   : (_) == 'I' ? 8                             \
+   : (_) == 'J' ? 9                             \
+   : (_) == 'K' ? 10                            \
+   : (_) == 'L' ? 11                            \
+   : (_) == 'M' ? 12                            \
+   : (_) == 'N' ? 13                            \
+   : (_) == 'O' ? 14                            \
+   : (_) == 'P' ? 15                            \
+   : (_) == 'Q' ? 16                            \
+   : (_) == 'R' ? 17                            \
+   : (_) == 'S' ? 18                            \
+   : (_) == 'T' ? 19                            \
+   : (_) == 'U' ? 20                            \
+   : (_) == 'V' ? 21                            \
+   : (_) == 'W' ? 22                            \
+   : (_) == 'X' ? 23                            \
+   : (_) == 'Y' ? 24                            \
+   : (_) == 'Z' ? 25                            \
+   : (_) == 'a' ? 26                            \
+   : (_) == 'b' ? 27                            \
+   : (_) == 'c' ? 28                            \
+   : (_) == 'd' ? 29                            \
+   : (_) == 'e' ? 30                            \
+   : (_) == 'f' ? 31                            \
+   : (_) == 'g' ? 32                            \
+   : (_) == 'h' ? 33                            \
+   : (_) == 'i' ? 34                            \
+   : (_) == 'j' ? 35                            \
+   : (_) == 'k' ? 36                            \
+   : (_) == 'l' ? 37                            \
+   : (_) == 'm' ? 38                            \
+   : (_) == 'n' ? 39                            \
+   : (_) == 'o' ? 40                            \
+   : (_) == 'p' ? 41                            \
+   : (_) == 'q' ? 42                            \
+   : (_) == 'r' ? 43                            \
+   : (_) == 's' ? 44                            \
+   : (_) == 't' ? 45                            \
+   : (_) == 'u' ? 46                            \
+   : (_) == 'v' ? 47                            \
+   : (_) == 'w' ? 48                            \
+   : (_) == 'x' ? 49                            \
+   : (_) == 'y' ? 50                            \
+   : (_) == 'z' ? 51                            \
+   : (_) == '0' ? 52                            \
+   : (_) == '1' ? 53                            \
+   : (_) == '2' ? 54                            \
+   : (_) == '3' ? 55                            \
+   : (_) == '4' ? 56                            \
+   : (_) == '5' ? 57                            \
+   : (_) == '6' ? 58                            \
+   : (_) == '7' ? 59                            \
+   : (_) == '8' ? 60                            \
+   : (_) == '9' ? 61                            \
+   : (_) == '+' ? 62                            \
+   : (_) == '/' ? 63                            \
+   : -1)
+
+static const signed char b64[0x100] = {
+  B64 (0), B64 (1), B64 (2), B64 (3),
+  B64 (4), B64 (5), B64 (6), B64 (7),
+  B64 (8), B64 (9), B64 (10), B64 (11),
+  B64 (12), B64 (13), B64 (14), B64 (15),
+  B64 (16), B64 (17), B64 (18), B64 (19),
+  B64 (20), B64 (21), B64 (22), B64 (23),
+  B64 (24), B64 (25), B64 (26), B64 (27),
+  B64 (28), B64 (29), B64 (30), B64 (31),
+  B64 (32), B64 (33), B64 (34), B64 (35),
+  B64 (36), B64 (37), B64 (38), B64 (39),
+  B64 (40), B64 (41), B64 (42), B64 (43),
+  B64 (44), B64 (45), B64 (46), B64 (47),
+  B64 (48), B64 (49), B64 (50), B64 (51),
+  B64 (52), B64 (53), B64 (54), B64 (55),
+  B64 (56), B64 (57), B64 (58), B64 (59),
+  B64 (60), B64 (61), B64 (62), B64 (63),
+  B64 (64), B64 (65), B64 (66), B64 (67),
+  B64 (68), B64 (69), B64 (70), B64 (71),
+  B64 (72), B64 (73), B64 (74), B64 (75),
+  B64 (76), B64 (77), B64 (78), B64 (79),
+  B64 (80), B64 (81), B64 (82), B64 (83),
+  B64 (84), B64 (85), B64 (86), B64 (87),
+  B64 (88), B64 (89), B64 (90), B64 (91),
+  B64 (92), B64 (93), B64 (94), B64 (95),
+  B64 (96), B64 (97), B64 (98), B64 (99),
+  B64 (100), B64 (101), B64 (102), B64 (103),
+  B64 (104), B64 (105), B64 (106), B64 (107),
+  B64 (108), B64 (109), B64 (110), B64 (111),
+  B64 (112), B64 (113), B64 (114), B64 (115),
+  B64 (116), B64 (117), B64 (118), B64 (119),
+  B64 (120), B64 (121), B64 (122), B64 (123),
+  B64 (124), B64 (125), B64 (126), B64 (127),
+  B64 (128), B64 (129), B64 (130), B64 (131),
+  B64 (132), B64 (133), B64 (134), B64 (135),
+  B64 (136), B64 (137), B64 (138), B64 (139),
+  B64 (140), B64 (141), B64 (142), B64 (143),
+  B64 (144), B64 (145), B64 (146), B64 (147),
+  B64 (148), B64 (149), B64 (150), B64 (151),
+  B64 (152), B64 (153), B64 (154), B64 (155),
+  B64 (156), B64 (157), B64 (158), B64 (159),
+  B64 (160), B64 (161), B64 (162), B64 (163),
+  B64 (164), B64 (165), B64 (166), B64 (167),
+  B64 (168), B64 (169), B64 (170), B64 (171),
+  B64 (172), B64 (173), B64 (174), B64 (175),
+  B64 (176), B64 (177), B64 (178), B64 (179),
+  B64 (180), B64 (181), B64 (182), B64 (183),
+  B64 (184), B64 (185), B64 (186), B64 (187),
+  B64 (188), B64 (189), B64 (190), B64 (191),
+  B64 (192), B64 (193), B64 (194), B64 (195),
+  B64 (196), B64 (197), B64 (198), B64 (199),
+  B64 (200), B64 (201), B64 (202), B64 (203),
+  B64 (204), B64 (205), B64 (206), B64 (207),
+  B64 (208), B64 (209), B64 (210), B64 (211),
+  B64 (212), B64 (213), B64 (214), B64 (215),
+  B64 (216), B64 (217), B64 (218), B64 (219),
+  B64 (220), B64 (221), B64 (222), B64 (223),
+  B64 (224), B64 (225), B64 (226), B64 (227),
+  B64 (228), B64 (229), B64 (230), B64 (231),
+  B64 (232), B64 (233), B64 (234), B64 (235),
+  B64 (236), B64 (237), B64 (238), B64 (239),
+  B64 (240), B64 (241), B64 (242), B64 (243),
+  B64 (244), B64 (245), B64 (246), B64 (247),
+  B64 (248), B64 (249), B64 (250), B64 (251),
+  B64 (252), B64 (253), B64 (254), B64 (255)
+};
+
+#if UCHAR_MAX == 255
+# define uchar_in_range(c) true
+#else
+# define uchar_in_range(c) ((c) <= 255)
+#endif
+
+/* Return true if CH is a character from the Base64 alphabet, and
+   false otherwise.  Note that '=' is padding and not considered to be
+   part of the alphabet.  */
+bool
+isbase64 (char ch)
+{
+  return uchar_in_range (to_uchar (ch)) && 0 <= b64[to_uchar (ch)];
+}
+
+/* Initialize decode-context buffer, CTX.  */
+void
+base64_decode_ctx_init (struct base64_decode_context *ctx)
+{
+  ctx->i = 0;
+}
+
+/* If CTX->i is 0 or 4, there are four or more bytes in [*IN..IN_END), and
+   none of those four is a newline, then return *IN.  Otherwise, copy up to
+   4 - CTX->i non-newline bytes from that range into CTX->buf, starting at
+   index CTX->i and setting CTX->i to reflect the number of bytes copied,
+   and return CTX->buf.  In either case, advance *IN to point to the byte
+   after the last one processed, and set *N_NON_NEWLINE to the number of
+   verified non-newline bytes accessible through the returned pointer.  */
+static inline char *
+get_4 (struct base64_decode_context *ctx,
+       char const *restrict *in, char const *restrict in_end,
+       size_t *n_non_newline)
+{
+  if (ctx->i == 4)
+    ctx->i = 0;
+
+  if (ctx->i == 0)
+    {
+      char const *t = *in;
+      if (4 <= in_end - *in && memchr (t, '\n', 4) == NULL)
+        {
+          /* This is the common case: no newline.  */
+          *in += 4;
+          *n_non_newline = 4;
+          return (char *) t;
+        }
+    }
+
+  {
+    /* Copy non-newline bytes into BUF.  */
+    char const *p = *in;
+    while (p < in_end)
+      {
+        char c = *p++;
+        if (c != '\n')
+          {
+            ctx->buf[ctx->i++] = c;
+            if (ctx->i == 4)
+              break;
+          }
+      }
+
+    *in = p;
+    *n_non_newline = ctx->i;
+    return ctx->buf;
+  }
+}
+
+#define return_false                            \
+  do                                            \
+    {                                           \
+      *outp = out;                              \
+      return false;                             \
+    }                                           \
+  while (false)
+
+/* Decode up to four bytes of base64-encoded data, IN, of length INLEN
+   into the output buffer, *OUT, of size *OUTLEN bytes.  Return true if
+   decoding is successful, false otherwise.  If *OUTLEN is too small,
+   as many bytes as possible are written to *OUT.  On return, advance
+   *OUT to point to the byte after the last one written, and decrement
+   *OUTLEN to reflect the number of bytes remaining in *OUT.  */
+static inline bool
+decode_4 (char const *restrict in, size_t inlen,
+          char *restrict *outp, size_t *outleft)
+{
+  char *out = *outp;
+  if (inlen < 2)
+    return false;
+
+  if (!isbase64 (in[0]) || !isbase64 (in[1]))
+    return false;
+
+  if (*outleft)
+    {
+      *out++ = ((b64[to_uchar (in[0])] << 2)
+                | (b64[to_uchar (in[1])] >> 4));
+      --*outleft;
+    }
+
+  if (inlen == 2)
+    return_false;
+
+  if (in[2] == '=')
+    {
+      if (inlen != 4)
+        return_false;
+
+      if (in[3] != '=')
+        return_false;
+    }
+  else
+    {
+      if (!isbase64 (in[2]))
+        return_false;
+
+      if (*outleft)
+        {
+          *out++ = (((b64[to_uchar (in[1])] << 4) & 0xf0)
+                    | (b64[to_uchar (in[2])] >> 2));
+          --*outleft;
+        }
+
+      if (inlen == 3)
+        return_false;
+
+      if (in[3] == '=')
+        {
+          if (inlen != 4)
+            return_false;
+        }
+      else
+        {
+          if (!isbase64 (in[3]))
+            return_false;
+
+          if (*outleft)
+            {
+              *out++ = (((b64[to_uchar (in[2])] << 6) & 0xc0)
+                        | b64[to_uchar (in[3])]);
+              --*outleft;
+            }
+        }
+    }
+
+  *outp = out;
+  return true;
+}
+
+/* Decode base64-encoded input array IN of length INLEN to output array
+   OUT that can hold *OUTLEN bytes.  The input data may be interspersed
+   with newlines.  Return true if decoding was successful, i.e. if the
+   input was valid base64 data, false otherwise.  If *OUTLEN is too
+   small, as many bytes as possible will be written to OUT.  On return,
+   *OUTLEN holds the length of decoded bytes in OUT.  Note that as soon
+   as any non-alphabet, non-newline character is encountered, decoding
+   is stopped and false is returned.  If INLEN is zero, then process
+   only whatever data is stored in CTX.
+
+   Initially, CTX must have been initialized via base64_decode_ctx_init.
+   Subsequent calls to this function must reuse whatever state is recorded
+   in that buffer.  It is necessary for when a quadruple of base64 input
+   bytes spans two input buffers.
+
+   If CTX is NULL then newlines are treated as garbage and the input
+   buffer is processed as a unit.  */
+
+bool
+base64_decode_ctx (struct base64_decode_context *ctx,
+                   const char *restrict in, size_t inlen,
+                   char *restrict out, size_t *outlen)
+{
+  size_t outleft = *outlen;
+  bool ignore_newlines = ctx != NULL;
+  bool flush_ctx = false;
+  unsigned int ctx_i = 0;
+
+  if (ignore_newlines)
+    {
+      ctx_i = ctx->i;
+      flush_ctx = inlen == 0;
+    }
+
+
+  while (true)
+    {
+      size_t outleft_save = outleft;
+      if (ctx_i == 0 && !flush_ctx)
+        {
+          while (true)
+            {
+              /* Save a copy of outleft, in case we need to re-parse this
+                 block of four bytes.  */
+              outleft_save = outleft;
+              if (!decode_4 (in, inlen, &out, &outleft))
+                break;
+
+              in += 4;
+              inlen -= 4;
+            }
+        }
+
+      if (inlen == 0 && !flush_ctx)
+        break;
+
+      /* Handle the common case of 72-byte wrapped lines.
+         This also handles any other multiple-of-4-byte wrapping.  */
+      if (inlen && *in == '\n' && ignore_newlines)
+        {
+          ++in;
+          --inlen;
+          continue;
+        }
+
+      /* Restore OUT and OUTLEFT.  */
+      out -= outleft_save - outleft;
+      outleft = outleft_save;
+
+      {
+        char const *in_end = in + inlen;
+        char const *non_nl;
+
+        if (ignore_newlines)
+          non_nl = get_4 (ctx, &in, in_end, &inlen);
+        else
+          non_nl = in;  /* Might have nl in this case. */
+
+        /* If the input is empty or consists solely of newlines (0 non-newlines),
+           then we're done.  Likewise if there are fewer than 4 bytes when not
+           flushing context and not treating newlines as garbage.  */
+        if (inlen == 0 || (inlen < 4 && !flush_ctx && ignore_newlines))
+          {
+            inlen = 0;
+            break;
+          }
+        if (!decode_4 (non_nl, inlen, &out, &outleft))
+          break;
+
+        inlen = in_end - in;
+      }
+    }
+
+  *outlen -= outleft;
+
+  return inlen == 0;
+}
+
+/* Allocate an output buffer in *OUT, and decode the base64 encoded
+   data stored in IN of size INLEN to the *OUT buffer.  On return, the
+   size of the decoded data is stored in *OUTLEN.  OUTLEN may be NULL,
+   if the caller is not interested in the decoded length.  *OUT may be
+   NULL to indicate an out of memory error, in which case *OUTLEN
+   contains the size of the memory block needed.  The function returns
+   true on successful decoding and memory allocation errors.  (Use the
+   *OUT and *OUTLEN parameters to differentiate between successful
+   decoding and memory error.)  The function returns false if the
+   input was invalid, in which case *OUT is NULL and *OUTLEN is
+   undefined. */
+bool
+base64_decode_alloc_ctx (struct base64_decode_context *ctx,
+                         const char *in, size_t inlen, char **out,
+                         size_t *outlen)
+{
+  /* This may allocate a few bytes too many, depending on input,
+     but it's not worth the extra CPU time to compute the exact size.
+     The exact size is 3 * (inlen + (ctx ? ctx->i : 0)) / 4, minus 1 if the
+     input ends with "=" and minus another 1 if the input ends with "==".
+     Dividing before multiplying avoids the possibility of overflow.  */
+  size_t needlen = 3 * (inlen / 4) + 3;
+
+  *out = malloc (needlen);
+  if (!*out)
+    return true;
+
+  if (!base64_decode_ctx (ctx, in, inlen, *out, &needlen))
+    {
+      free (*out);
+      *out = NULL;
+      return false;
+    }
+
+  if (outlen)
+    *outlen = needlen;
+
+  return true;
+}
diff --git a/project_files/frontlib/base64/base64.h b/project_files/frontlib/base64/base64.h
new file mode 100644
index 0000000..f71e4aa
--- /dev/null
+++ b/project_files/frontlib/base64/base64.h
@@ -0,0 +1,60 @@
+/* base64.h -- Encode binary data using printable characters.
+   Copyright (C) 2004-2006, 2009-2012 Free Software Foundation, Inc.
+   Written by Simon Josefsson.
+
+   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; either version 2, or (at your option)
+   any later version.
+
+   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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef BASE64_H
+# define BASE64_H
+
+/* Get size_t. */
+# include <stddef.h>
+
+/* Get bool. */
+# include <stdbool.h>
+
+/*! This uses that the expression (n+(k-1))/k means the smallest
+   integer >= n/k, i.e., the ceiling of n/k.  */
+# define BASE64_LENGTH(inlen) ((((inlen) + 2) / 3) * 4)
+
+struct base64_decode_context
+{
+  unsigned int i;
+  char buf[4];
+};
+
+extern bool isbase64 (char ch);
+
+extern void base64_encode (const char *restrict in, size_t inlen,
+                           char *restrict out, size_t outlen);
+
+extern size_t base64_encode_alloc (const char *in, size_t inlen, char **out);
+
+extern void base64_decode_ctx_init (struct base64_decode_context *ctx);
+
+extern bool base64_decode_ctx (struct base64_decode_context *ctx,
+                               const char *restrict in, size_t inlen,
+                               char *restrict out, size_t *outlen);
+
+extern bool base64_decode_alloc_ctx (struct base64_decode_context *ctx,
+                                     const char *in, size_t inlen,
+                                     char **out, size_t *outlen);
+
+#define base64_decode(in, inlen, out, outlen) \
+        base64_decode_ctx (NULL, in, inlen, out, outlen)
+
+#define base64_decode_alloc(in, inlen, out, outlen) \
+        base64_decode_alloc_ctx (NULL, in, inlen, out, outlen)
+
+#endif /* BASE64_H */
diff --git a/project_files/frontlib/extra/jnacontrol.c b/project_files/frontlib/extra/jnacontrol.c
new file mode 100644
index 0000000..d490e6c
--- /dev/null
+++ b/project_files/frontlib/extra/jnacontrol.c
@@ -0,0 +1,240 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/*
+ * This file is not directly part of the frontlib and is not required to build it.
+ * However, it is recommended to include it in compilation when building for Android. The purpose of this file
+ * is to ensure consistency between the function signatures of the JNA Java bindings of the Android port and the
+ * frontlib functions.
+ *
+ * This file, in essence, consists only of function declarations. They are duplicates of function declarations
+ * from the frontlib headers that are referenced from JNA bindings. If the signature of one of these functions
+ * changes in the frontlib, it will no longer match the signature in this file, and the compiler will show an error.
+ * If that happens, you need to update the JNA bindings in Hedgeroid to match the new function signature, and then
+ * update this file.
+ *
+ * The reason for all this is that JNA does not actually know the function signatures of the functions it binds,
+ * it derives them from Java method declarations. If those do not match the actual function signatures, you will
+ * only notice when you suddenly get strange (and possibly hard to track down) problems at runtime. This file is
+ * an attempt to detect these problems at compile time instead. Notice that it will NOT detect changes to structs
+ * or constants though, which also require updates to the JNA bindings.
+ */
+
+/*
+ * Before we include the frontlib headers, we define away the const keyword. This is necessary because there is no
+ * distinction between const and non-const types on the JNA side, and we don't want the compiler to complain because
+ * of bad constness.
+ *
+ * This is so evil, but it works...
+ */
+#define const
+
+#include "../frontlib.h"
+
+/*
+ * Now we map the Java types to the corresponding C types...
+ */
+typedef flib_netconn *NetconnPtr;
+typedef flib_gameconn *GameconnPtr;
+typedef flib_mapconn *MapconnPtr;
+typedef flib_metascheme *MetaschemePtr;
+typedef flib_room **RoomArrayPtr;
+typedef flib_weaponset *WeaponsetPtr;
+typedef flib_weaponsetlist *WeaponsetListPtr;
+typedef flib_map *MapRecipePtr;
+typedef flib_scheme *SchemePtr;
+typedef flib_schemelist *SchemelistPtr;
+
+typedef flib_room *RoomPtr;
+typedef flib_team *TeamPtr;
+typedef flib_gamesetup *GameSetupPtr;
+typedef bool boolean;
+typedef size_t NativeSizeT;
+typedef void *Pointer;
+typedef uint8_t *ByteArrayPtr;
+typedef char *String;
+
+/*
+ * Mapping callback types
+ */
+typedef void (*VoidCallback)(Pointer context);
+typedef void (*StrCallback)(Pointer context, String arg1);
+typedef void (*IntCallback)(Pointer context, int arg1);
+typedef void (*IntStrCallback)(Pointer context, int arg1, String arg2);
+typedef void (*StrIntCallback)(Pointer context, String arg1, int arg2);
+typedef void (*StrStrCallback)(Pointer context, String arg1, String arg2);
+typedef void (*StrStrBoolCallback)(Pointer context, String arg1, String arg2, boolean arg3);
+typedef void (*RoomCallback)(Pointer context, RoomPtr arg1);
+typedef void (*RoomListCallback)(Pointer context, RoomArrayPtr arg1, int arg2);
+typedef void (*StrRoomCallback)(Pointer context, String arg1, RoomPtr arg2);
+typedef void (*BoolCallback)(Pointer context, boolean arg1);
+typedef void (*StrBoolCallback)(Pointer context, String arg1, boolean arg2);
+typedef void (*TeamCallback)(Pointer context, TeamPtr arg1);
+typedef void (*BytesCallback)(Pointer context, const uint8_t *buffer, NativeSizeT size);
+typedef void (*BytesBoolCallback)(Pointer context, const uint8_t *buffer, NativeSizeT size, boolean arg3);
+typedef void (*SchemeCallback)(Pointer context, SchemePtr arg1);
+typedef void (*MapIntCallback)(Pointer context, MapRecipePtr arg1, int arg2);
+typedef void (*WeaponsetCallback)(Pointer context, WeaponsetPtr arg1);
+typedef void (*MapimageCallback)(Pointer context, const uint8_t *mapimage, int hogs);
+typedef void (*LogCallback)(int arg1, String arg2);
+
+/*
+ * Below here are the copypasted method declarations from the JNA bindings
+ */
+
+	// frontlib.h
+    int flib_init();
+    void flib_quit();
+
+    // hwconsts.h
+    int flib_get_teamcolor_count();
+    int flib_get_hedgehogs_per_team();
+    int flib_get_weapons_count();
+	MetaschemePtr flib_get_metascheme();
+
+    // net/netconn.h
+	NetconnPtr flib_netconn_create(String playerName, String dataDirPath, String host, int port);
+	void flib_netconn_destroy(NetconnPtr conn);
+
+	void flib_netconn_tick(NetconnPtr conn);
+	boolean flib_netconn_is_chief(NetconnPtr conn);
+	String flib_netconn_get_playername(NetconnPtr conn);
+	GameSetupPtr flib_netconn_create_gamesetup(NetconnPtr conn);
+	int flib_netconn_send_quit(NetconnPtr conn, String quitmsg);
+	int flib_netconn_send_chat(NetconnPtr conn, String chat);
+	int flib_netconn_send_teamchat(NetconnPtr conn, String msg);
+	int flib_netconn_send_password(NetconnPtr conn, String passwd);
+	int flib_netconn_send_nick(NetconnPtr conn, String nick);
+	int flib_netconn_send_request_roomlist(NetconnPtr conn);
+	int flib_netconn_send_joinRoom(NetconnPtr conn, String room);
+	int flib_netconn_send_createRoom(NetconnPtr conn, String room);
+	int flib_netconn_send_renameRoom(NetconnPtr conn, String roomName);
+	int flib_netconn_send_leaveRoom(NetconnPtr conn, String msg);
+	int flib_netconn_send_toggleReady(NetconnPtr conn);
+	int flib_netconn_send_addTeam(NetconnPtr conn, TeamPtr team);
+	int flib_netconn_send_removeTeam(NetconnPtr conn, String teamname);
+	int flib_netconn_send_engineMessage(NetconnPtr conn, ByteArrayPtr message, NativeSizeT size);
+	int flib_netconn_send_teamHogCount(NetconnPtr conn, String teamname, int hogcount);
+	int flib_netconn_send_teamColor(NetconnPtr conn, String teamname, int colorIndex);
+	int flib_netconn_send_weaponset(NetconnPtr conn, WeaponsetPtr weaponset);
+	int flib_netconn_send_map(NetconnPtr conn, MapRecipePtr map);
+	int flib_netconn_send_mapName(NetconnPtr conn, String mapName);
+	int flib_netconn_send_mapGen(NetconnPtr conn, int mapGen);
+	int flib_netconn_send_mapTemplate(NetconnPtr conn, int templateFilter);
+	int flib_netconn_send_mapMazeSize(NetconnPtr conn, int mazeSize);
+	int flib_netconn_send_mapSeed(NetconnPtr conn, String seed);
+	int flib_netconn_send_mapTheme(NetconnPtr conn, String theme);
+	int flib_netconn_send_mapDrawdata(NetconnPtr conn, ByteArrayPtr drawData, NativeSizeT size);
+	int flib_netconn_send_script(NetconnPtr conn, String scriptName);
+	int flib_netconn_send_scheme(NetconnPtr conn, SchemePtr scheme);
+	int flib_netconn_send_roundfinished(NetconnPtr conn, boolean withoutError);
+	int flib_netconn_send_ban(NetconnPtr conn, String playerName);
+	int flib_netconn_send_kick(NetconnPtr conn, String playerName);
+	int flib_netconn_send_playerInfo(NetconnPtr conn, String playerName);
+	int flib_netconn_send_playerFollow(NetconnPtr conn, String playerName);
+	int flib_netconn_send_startGame(NetconnPtr conn);
+	int flib_netconn_send_toggleRestrictJoins(NetconnPtr conn);
+	int flib_netconn_send_toggleRestrictTeams(NetconnPtr conn);
+	int flib_netconn_send_clearAccountsCache(NetconnPtr conn);
+	int flib_netconn_send_setServerVar(NetconnPtr conn, String name, String value);
+	int flib_netconn_send_getServerVars(NetconnPtr conn);
+
+	void flib_netconn_onMessage(NetconnPtr conn, IntStrCallback callback, Pointer context);
+	void flib_netconn_onClientFlags(NetconnPtr conn, StrStrBoolCallback callback, Pointer context);
+	void flib_netconn_onChat(NetconnPtr conn, StrStrCallback callback, Pointer context);
+	void flib_netconn_onConnected(NetconnPtr conn, VoidCallback callback, Pointer context);
+	void flib_netconn_onDisconnected(NetconnPtr conn, IntStrCallback callback, Pointer context);
+	void flib_netconn_onRoomlist(NetconnPtr conn, RoomListCallback callback, Pointer context);
+	void flib_netconn_onRoomAdd(NetconnPtr conn, RoomCallback callback, Pointer context);
+	void flib_netconn_onRoomDelete(NetconnPtr conn, StrCallback callback, Pointer context);
+	void flib_netconn_onRoomUpdate(NetconnPtr conn, StrRoomCallback callback, Pointer context);
+	void flib_netconn_onLobbyJoin(NetconnPtr conn, StrCallback callback, Pointer context);
+	void flib_netconn_onLobbyLeave(NetconnPtr conn, StrStrCallback callback, Pointer context);
+	void flib_netconn_onNickTaken(NetconnPtr conn, StrCallback callback, Pointer context);
+	void flib_netconn_onPasswordRequest(NetconnPtr conn, StrCallback callback, Pointer context);
+	void flib_netconn_onEnterRoom(NetconnPtr conn, BoolCallback callback, Pointer context);
+	void flib_netconn_onLeaveRoom(NetconnPtr conn, IntStrCallback callback, Pointer context);
+	void flib_netconn_onTeamAdd(NetconnPtr conn, TeamCallback callback, Pointer context);
+	void flib_netconn_onTeamDelete(NetconnPtr conn, StrCallback callback, Pointer context);
+	void flib_netconn_onRoomJoin(NetconnPtr conn, StrCallback callback, Pointer context);
+	void flib_netconn_onRoomLeave(NetconnPtr conn, StrStrCallback callback, Pointer context);
+	void flib_netconn_onRunGame(NetconnPtr conn, VoidCallback callback, Pointer context);
+	void flib_netconn_onTeamAccepted(NetconnPtr conn, StrCallback callback, Pointer context);
+	void flib_netconn_onHogCountChanged(NetconnPtr conn, StrIntCallback callback, Pointer context);
+	void flib_netconn_onTeamColorChanged(NetconnPtr conn, StrIntCallback callback, Pointer context);
+	void flib_netconn_onEngineMessage(NetconnPtr conn, BytesCallback callback, Pointer context);
+	void flib_netconn_onSchemeChanged(NetconnPtr conn, SchemeCallback callback, Pointer context);
+	void flib_netconn_onMapChanged(NetconnPtr conn, MapIntCallback callback, Pointer context);
+	void flib_netconn_onScriptChanged(NetconnPtr conn, StrCallback callback, Pointer context);
+	void flib_netconn_onWeaponsetChanged(NetconnPtr conn, WeaponsetCallback callback, Pointer context);
+	void flib_netconn_onServerVar(NetconnPtr conn, StrStrCallback callback, Pointer context);
+
+	// ipc/gameconn.h
+
+	GameconnPtr flib_gameconn_create(String playerName, GameSetupPtr setup, boolean netgame);
+	GameconnPtr flib_gameconn_create_playdemo(ByteArrayPtr demo, NativeSizeT size);
+	GameconnPtr flib_gameconn_create_loadgame(String playerName, ByteArrayPtr save, NativeSizeT size);
+	GameconnPtr flib_gameconn_create_campaign(String playerName, String seed, String script);
+
+	void flib_gameconn_destroy(GameconnPtr conn);
+	int flib_gameconn_getport(GameconnPtr conn);
+	void flib_gameconn_tick(GameconnPtr conn);
+
+	int flib_gameconn_send_enginemsg(GameconnPtr conn, ByteArrayPtr data, NativeSizeT len);
+	int flib_gameconn_send_textmsg(GameconnPtr conn, int msgtype, String msg);
+	int flib_gameconn_send_chatmsg(GameconnPtr conn, String playername, String msg);
+	int flib_gameconn_send_quit(GameconnPtr conn);
+	int flib_gameconn_send_cmd(GameconnPtr conn, String cmdString);
+
+	void flib_gameconn_onConnect(GameconnPtr conn, VoidCallback callback, Pointer context);
+	void flib_gameconn_onDisconnect(GameconnPtr conn, IntCallback callback, Pointer context);
+	void flib_gameconn_onErrorMessage(GameconnPtr conn, StrCallback callback, Pointer context);
+	void flib_gameconn_onChat(GameconnPtr conn, StrBoolCallback callback, Pointer context);
+	void flib_gameconn_onGameRecorded(GameconnPtr conn, BytesBoolCallback callback, Pointer context);
+	void flib_gameconn_onEngineMessage(GameconnPtr conn, BytesCallback callback, Pointer context);
+
+	// ipc/mapconn.h
+	MapconnPtr flib_mapconn_create(MapRecipePtr mapdesc);
+	void flib_mapconn_destroy(MapconnPtr conn);
+	int flib_mapconn_getport(MapconnPtr conn);
+	void flib_mapconn_onSuccess(MapconnPtr conn, MapimageCallback callback, Pointer context);
+	void flib_mapconn_onFailure(MapconnPtr conn, StrCallback callback, Pointer context);
+	void flib_mapconn_tick(MapconnPtr conn);
+
+	// model/schemelist.h
+	SchemelistPtr flib_schemelist_from_ini(String filename);
+	int flib_schemelist_to_ini(String filename, SchemelistPtr list);
+	void flib_schemelist_destroy(SchemelistPtr list);
+
+	// model/team.h
+	TeamPtr flib_team_from_ini(String filename);
+	int flib_team_to_ini(String filename, TeamPtr team);
+	void flib_team_destroy(TeamPtr team);
+
+	// model/weapon.h
+	WeaponsetListPtr flib_weaponsetlist_from_ini(String filename);
+	int flib_weaponsetlist_to_ini(String filename, WeaponsetListPtr weaponsets);
+	void flib_weaponsetlist_destroy(WeaponsetListPtr list);
+
+	// model/gamesetup.h
+	void flib_gamesetup_destroy(GameSetupPtr gamesetup);
+
+	// util/logging.h
+    void flib_log_setLevel(int level);
+    void flib_log_setCallback(LogCallback callback);
diff --git a/project_files/frontlib/frontlib.c b/project_files/frontlib/frontlib.c
new file mode 100644
index 0000000..eee4a00
--- /dev/null
+++ b/project_files/frontlib/frontlib.c
@@ -0,0 +1,37 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "frontlib.h"
+#include "util/logging.h"
+#include <SDL_net.h>
+
+int flib_init() {
+	flib_log_d("Initializing frontlib");
+	if(SDLNet_Init()==-1) {
+		flib_log_e("Error in SDLNet_Init: %s", SDLNet_GetError());
+		return -1;
+	}
+
+	return 0;
+}
+
+void flib_quit() {
+	flib_log_d("Shutting down frontlib");
+	SDLNet_Quit();
+}
diff --git a/project_files/frontlib/frontlib.h b/project_files/frontlib/frontlib.h
new file mode 100644
index 0000000..2526d3c
--- /dev/null
+++ b/project_files/frontlib/frontlib.h
@@ -0,0 +1,48 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/*
+ * Public header file for the hedgewars frontent networking library.
+ *
+ * This is the only header you should need to include from frontend code.
+ */
+
+#ifndef FRONTLIB_H_
+#define FRONTLIB_H_
+
+#include "ipc/gameconn.h"
+#include "ipc/mapconn.h"
+#include "net/netconn.h"
+#include "util/logging.h"
+#include "model/schemelist.h"
+
+/**
+ * Call this function before anything else in this library.
+ * Returns 0 on success, -1 on error.
+ */
+int flib_init();
+
+/**
+ * Free resources associated with the library. Call this function once
+ * the library is no longer needed. You can re-initialize the library by calling
+ * flib_init again.
+ */
+void flib_quit();
+
+#endif /* FRONTLIB_H_ */
diff --git a/project_files/frontlib/hw_doc.doxygen b/project_files/frontlib/hw_doc.doxygen
new file mode 100644
index 0000000..d8bda92
--- /dev/null
+++ b/project_files/frontlib/hw_doc.doxygen
@@ -0,0 +1,1846 @@
+# Doxyfile 1.8.2
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file 
+# that follow. The default is UTF-8 which is also the encoding used for all 
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
+# iconv built into libc) for the transcoding. See 
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or sequence of words) that should 
+# identify the project. Note that if you do not use Doxywizard you need 
+# to put quotes around the project name if it contains spaces.
+
+PROJECT_NAME           = "HW Frontlib"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = ""
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description 
+# for a project that appears at the top of each page and should give viewer 
+# a quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          = 
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is 
+# included in the documentation. The maximum height of the logo should not 
+# exceed 55 pixels and the maximum width should not exceed 200 pixels. 
+# Doxygen will copy the logo to the output directory.
+
+PROJECT_LOGO           = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = "doc"
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, 
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English 
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, 
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, 
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip. Note that you specify absolute paths here, but also 
+# relative paths, which will be relative from the directory where doxygen is 
+# started.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful if your file system 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like regular Qt-style comments 
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
+# interpret the first line (until the first dot) of a Qt-style 
+# comment as the brief description. If set to NO, the comments 
+# will behave just like regular Qt-style comments (thus requiring 
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only). 
+# A mapping has the form "name=value". For example adding 
+# "class=itcl::class" will allow you to use the command class in the 
+# itcl::class meaning.
+
+TCL_SUBST              = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Java. For instance, namespaces will be presented as packages, qualified 
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
+# sources. Doxygen will then generate output that is tailored for 
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it 
+# parses. With this tag you can assign which parser to use for a given 
+# extension. Doxygen has a built-in mapping, but you can override or extend it 
+# using this tag. The format is ext=language, where ext is a file extension, 
+# and language is one of the parsers supported by doxygen: IDL, Java, 
+# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, 
+# C++. For instance to make doxygen treat .inc files as Fortran files (default 
+# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note 
+# that for custom extensions you also need to set FILE_PATTERNS otherwise the 
+# files are not read by doxygen.
+
+EXTENSION_MAPPING      = 
+
+# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all 
+# comments according to the Markdown format, which allows for more readable 
+# documentation. See http://daringfireball.net/projects/markdown/ for details. 
+# The output of markdown processing is further processed by doxygen, so you 
+# can mix doxygen, HTML, and XML commands with Markdown formatting. 
+# Disable only in case of backward compatibilities issues.
+
+MARKDOWN_SUPPORT       = YES
+
+# When enabled doxygen tries to link words that correspond to documented classes, 
+# or namespaces to their corresponding documentation. Such a link can be 
+# prevented in individual cases by by putting a % sign in front of the word or 
+# globally by setting AUTOLINK_SUPPORT to NO.
+
+AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
+# to include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also makes the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to 
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
+# Doxygen will parse them like normal C++ but will assume all classes use public 
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES (the
+# default) will make doxygen replace the get and set methods by a property in
+# the documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and 
+# unions are shown inside the group in which they are included (e.g. using 
+# @ingroup) instead of on a separate page (for HTML and Man pages) or 
+# section (for LaTeX and RTF).
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and 
+# unions with only public data fields will be shown inline in the documentation 
+# of the scope in which they are defined (i.e. file, namespace, or group 
+# documentation), provided this scope is documented. If set to NO (the default), 
+# structs, classes, and unions are shown on a separate page (for HTML and Man 
+# pages) or section (for LaTeX and RTF).
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
+# is documented as struct, union, or enum with the name of the typedef. So 
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
+# with name TypeT. When disabled the typedef will appear as a member of a file, 
+# namespace, or class. And the struct will be named TypeS. This can typically 
+# be useful for C code in case the coding convention dictates that all compound 
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to 
+# determine which symbols to keep in memory and which to flush to disk. 
+# When the cache is full, less often used symbols will be written to disk. 
+# For small to medium size projects (<1000 input files) the default value is 
+# probably good enough. For larger projects a too small cache size can cause 
+# doxygen to be busy swapping symbols to and from disk most of the time 
+# causing a significant performance penalty. 
+# If the system has enough physical memory increasing the cache will improve the 
+# performance by keeping more symbols in memory. Note that the value works on 
+# a logarithmic scale so increasing the size by one will roughly double the 
+# memory usage. The cache size is given by this formula: 
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, 
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+SYMBOL_CACHE_SIZE      = 0
+
+# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be 
+# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given 
+# their name and scope. Since this can be an expensive process and often the 
+# same symbol appear multiple times in the code, doxygen keeps a cache of 
+# pre-resolved symbols. If the cache is too small doxygen will become slower. 
+# If the cache is too large, memory is wasted. The cache size is given by this 
+# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, 
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal 
+# scope will be included in the documentation.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be 
+# extracted and appear in the documentation as a namespace called 
+# 'anonymous_namespace{file}', where file will be replaced with the base 
+# name of the file that contains the anonymous namespace. By default 
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen 
+# will list include files with double quotes in the documentation 
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen 
+# will sort the (brief and detailed) documentation of class members so that 
+# constructors and destructors are listed first. If set to NO (the default) 
+# the constructors will appear in the respective orders defined by 
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. 
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO 
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
+# hierarchy of group names into alphabetical order. If set to NO (the default) 
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. 
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to 
+# do proper type resolution of all parameters of a function it will reject a 
+# match between the prototype and the implementation of a member function even 
+# if there is only one candidate or it is obvious which candidate to choose 
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen 
+# will still accept a match between prototype and implementation in such cases.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or macro consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and macros in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. 
+# This will remove the Files entry from the Quick Index and from the 
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the 
+# Namespaces page.  This will remove the Namespaces entry from the Quick Index 
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from 
+# the version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed 
+# by doxygen. The layout file controls the global structure of the generated 
+# output files in an output format independent way. To create the layout file 
+# that represents doxygen's defaults, run doxygen with the -l option. 
+# You can optionally specify a file name after the option, if omitted 
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE            = 
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files 
+# containing the references data. This must be a list of .bib files. The 
+# .bib extension is automatically appended if omitted. Using this command 
+# requires the bibtex tool to be installed. See also 
+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style 
+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this 
+# feature you need bibtex and perl available in the search path.
+
+CITE_BIB_FILES         = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = .
+
+# This tag can be used to specify the character encoding of the source files 
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
+# also the default input encoding. Doxygen uses libiconv (or the iconv built 
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh 
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py 
+# *.f90 *.f *.for *.vhd *.vhdl
+
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.d \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.idl \
+                         *.odl \
+                         *.cs \
+                         *.php \
+                         *.php3 \
+                         *.inc \
+                         *.m \
+                         *.markdown \
+                         *.md \
+                         *.mm \
+                         *.dox \
+                         *.py \
+                         *.f90 \
+                         *.f \
+                         *.for \
+                         *.vhd \
+                         *.vhdl
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag. 
+# Note that relative paths are relative to the directory from which doxygen is 
+# run.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or 
+# directories that are symbolic links (a Unix file system feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the 
+# output. The symbol name can be a fully qualified name, a word, or if the 
+# wildcard * is used, a substring. Examples: ANamespace, AClass, 
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty or if 
+# non of the patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file 
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) 
+# and it is also possible to disable source filtering for a specific pattern 
+# using *.ext= (so without naming a filter). This option only has effect when 
+# FILTER_SOURCE_FILES is enabled.
+
+FILTER_SOURCE_PATTERNS = 
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C, C++ and Fortran comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) 
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from 
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will 
+# link to the source code.  Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header. Note that when using a custom header you are responsible  
+# for the proper inclusion of any scripts and style sheets that doxygen 
+# needs, which is dependent on the configuration options used. 
+# It is advised to generate a default header using "doxygen -w html 
+# header.html footer.html stylesheet.css YourConfigFile" and then modify 
+# that header. Note that the header is subject to change so you typically 
+# have to redo this when upgrading to a newer version of doxygen or when 
+# changing the value of configuration settings such as GENERATE_TREEVIEW!
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If left blank doxygen will 
+# generate a default style sheet. Note that it is recommended to use 
+# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this 
+# tag will in the future become obsolete.
+
+HTML_STYLESHEET        = 
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional 
+# user-defined cascading style sheet that is included after the standard 
+# style sheets created by doxygen. Using this option one can overrule 
+# certain style aspects. This is preferred over using HTML_STYLESHEET 
+# since it does not replace the standard style sheet and is therefor more 
+# robust against future updates. Doxygen will copy the style sheet file to 
+# the output directory.
+
+HTML_EXTRA_STYLESHEET  = 
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or 
+# other source files which should be copied to the HTML output directory. Note 
+# that these files will be copied to the base HTML output directory. Use the 
+# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these 
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that 
+# the files will be copied as-is; there are no commands or markers available.
+
+HTML_EXTRA_FILES       = 
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. 
+# Doxygen will adjust the colors in the style sheet and background images 
+# according to this color. Hue is specified as an angle on a colorwheel, 
+# see http://en.wikipedia.org/wiki/Hue for more information. 
+# For instance the value 0 represents red, 60 is yellow, 120 is green, 
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. 
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of 
+# the colors in the HTML output. For a value of 0 the output will use 
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to 
+# the luminance component of the colors in the HTML output. Values below 
+# 100 gradually make the output lighter, whereas values above 100 make 
+# the output darker. The value divided by 100 is the actual gamma applied, 
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, 
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML 
+# page will contain the date and time when the page was generated. Setting 
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
+# documentation will contain sections that can be hidden and shown after the 
+# page has loaded.
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of 
+# entries shown in the various tree structured indices initially; the user 
+# can expand and collapse entries dynamically later on. Doxygen will expand 
+# the tree to such a level that at most the specified number of entries are 
+# visible (unless a fully collapsed tree already exceeds this amount). 
+# So setting the number of entries 1 will produce a full collapsed tree by 
+# default. 0 is a special value representing an infinite number of entries 
+# and will result in a full expanded tree by default.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files 
+# will be generated that can be used as input for Apple's Xcode 3 
+# integrated development environment, introduced with OSX 10.5 (Leopard). 
+# To create a documentation set, doxygen will generate a Makefile in the 
+# HTML output directory. Running make will produce the docset in that 
+# directory and running "make install" will install the docset in 
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
+# it at startup. 
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html 
+# for more information.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
+# feed. A documentation feed provides an umbrella under which multiple 
+# documentation sets from a single provider (such as a company or product suite) 
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
+# should uniquely identify the documentation set bundle. This should be a 
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely 
+# identify the documentation publisher. This should be a reverse domain-name 
+# style string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING 
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file 
+# content.
+
+CHM_INDEX_ENCODING     = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and 
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated 
+# that can be used as input for Qt's qhelpgenerator to generate a 
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can 
+# be used to specify the file name of the resulting .qch file. 
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to 
+# add. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the 
+# custom filter to add. For more information please see 
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> 
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this 
+# project's 
+# filter section matches. 
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> 
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can 
+# be used to specify the location of Qt's qhelpgenerator. 
+# If non-empty doxygen will try to run qhelpgenerator on the generated 
+# .qhp file.
+
+QHG_LOCATION           = 
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files  
+# will be generated, which together with the HTML files, form an Eclipse help 
+# plugin. To install this plugin and make it available under the help contents 
+# menu in Eclipse, the contents of the directory containing the HTML and XML 
+# files needs to be copied into the plugins directory of eclipse. The name of 
+# the directory within the plugins directory should be the same as 
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before 
+# the help appears.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin 
+# the directory name containing the HTML and XML files should also have 
+# this name.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) 
+# at top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it. Since the tabs have the same information as the 
+# navigation tree you can set this option to NO if you already set 
+# GENERATE_TREEVIEW to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index 
+# structure should be generated to display hierarchical information. 
+# If the tag value is set to YES, a side panel will be generated 
+# containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). 
+# Windows users are probably better off using the HTML help feature. 
+# Since the tree basically has the same information as the tab index you 
+# could consider to set DISABLE_INDEX to NO when enabling this option.
+
+GENERATE_TREEVIEW      = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values 
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML 
+# documentation. Note that a value of 0 will completely suppress the enum 
+# values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open 
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of Latex formulas included 
+# as images in the HTML documentation. The default is 10. Note that 
+# when you change the font size after a successful doxygen run you need 
+# to manually remove any form_*.png images from the HTML output directory 
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images 
+# generated for formulas are transparent PNGs. Transparent PNGs are 
+# not supported properly for IE 6.0, but are supported on all modern browsers. 
+# Note that when changing this option you need to delete any form_*.png files 
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax 
+# (see http://www.mathjax.org) which uses client side Javascript for the 
+# rendering instead of using prerendered bitmaps. Use this if you do not 
+# have LaTeX installed or if you want to formulas look prettier in the HTML 
+# output. When enabled you may also need to install MathJax separately and 
+# configure the path to it using the MATHJAX_RELPATH option.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you need to specify the location relative to the 
+# HTML output directory using the MATHJAX_RELPATH option. The destination 
+# directory should contain the MathJax.js script. For instance, if the mathjax 
+# directory is located at the same level as the HTML output directory, then 
+# MATHJAX_RELPATH should be ../mathjax. The default value points to 
+# the MathJax Content Delivery Network so you can quickly see the result without 
+# installing MathJax.  However, it is strongly recommended to install a local 
+# copy of MathJax from http://www.mathjax.org before deployment.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension 
+# names that should be enabled during MathJax rendering.
+
+MATHJAX_EXTENSIONS     = 
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box 
+# for the HTML output. The underlying search engine uses javascript 
+# and DHTML and should work on any modern browser. Note that when using 
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets 
+# (GENERATE_DOCSET) there is already a search function so this one should 
+# typically be disabled. For large projects the javascript based search engine 
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be 
+# implemented using a PHP enabled web server instead of at the web client 
+# using Javascript. Doxygen will generate the search PHP script and index 
+# file to put on the web server. The advantage of the server 
+# based approach is that it scales better to large projects and allows 
+# full text search. The disadvantages are that it is more difficult to setup 
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name. 
+# Note that when enabling USE_PDFLATEX this option is only used for 
+# generating bitmaps for formulas in the HTML output, but not in the 
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for 
+# the generated latex document. The footer should contain everything after 
+# the last chapter. If it is left blank doxygen will generate a 
+# standard footer. Notice: only use this tag if you know what you are doing!
+
+LATEX_FOOTER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include 
+# source code with syntax highlighting in the LaTeX output. 
+# Note that which sources are shown also depends on other settings 
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the 
+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See 
+# http://en.wikipedia.org/wiki/BibTeX for more info.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load style sheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# pointed to by INCLUDE_PATH will be searched when a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition that 
+# overrules the definition found in the source code.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all references to function-like macros 
+# that are alone on a line, have an all uppercase name, and do not end with a 
+# semicolon, because these will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. For each 
+# tag file the location of the external documentation should be added. The 
+# format of a tag file without this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths 
+# or URLs. Note that each tag file must have a unique name (where the name does 
+# NOT include the path). If a tag file is not located in the directory in which 
+# doxygen is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option also works with HAVE_DOT disabled, but it is recommended to 
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS         = NO
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see 
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
+# the mscgen tool resides. If left empty the tool is assumed to be found in the 
+# default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = YES
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is 
+# allowed to run in parallel. When set to 0 (the default) doxygen will 
+# base this on the number of processors available in the system. You can set it 
+# explicitly to a value larger than 0 to get control over the balance 
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS        = 0
+
+# By default doxygen will use the Helvetica font for all dot files that 
+# doxygen generates. When you want a differently looking font you can specify 
+# the font name using DOT_FONTNAME. You need to make sure dot is able to find 
+# the font, which can be done by putting it in a standard location or by setting 
+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the 
+# directory containing the font.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. 
+# The default size is 10pt.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the Helvetica font. 
+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to 
+# set the path where dot can find it.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside 
+# the class node. If there are many fields or methods and many nodes the 
+# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS 
+# threshold limits the number of items for each type to make the size more 
+# managable. Set this to 0 for no limit. Note that the threshold may be 
+# exceeded by 50% before the limit is enforced.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then 
+# doxygen will generate a call dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable call graphs 
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
+# doxygen will generate a caller dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable caller 
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include 
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are svg, png, jpg, or gif. 
+# If left blank png will be used. If you choose svg you need to set 
+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files 
+# visible in IE 9+ (other browsers do not have this requirement).
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to 
+# enable generation of interactive SVG images that allow zooming and panning. 
+# Note that this requires a modern browser other than Internet Explorer. 
+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you 
+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files 
+# visible. Older versions of IE do not have SVG support.
+
+INTERACTIVE_SVG        = NO
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that 
+# contain msc files that are included in the documentation (see the 
+# \mscfile command).
+
+MSCFILE_DIRS           = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen if the 
+# number of direct children of the root node in a graph is already larger than 
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that the size of a graph can be further restricted by 
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, because dot on Windows does not 
+# seem to support this out of the box. Warning: Depending on the platform used, 
+# enabling this option may lead to badly anti-aliased labels on the edges of 
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
diff --git a/project_files/frontlib/hwconsts.c b/project_files/frontlib/hwconsts.c
new file mode 100644
index 0000000..98ec8c3
--- /dev/null
+++ b/project_files/frontlib/hwconsts.c
@@ -0,0 +1,100 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "hwconsts.h"
+
+const uint32_t flib_teamcolors[] = HW_TEAMCOLOR_ARRAY;
+const size_t flib_teamcolor_count = sizeof(flib_teamcolors)/sizeof(uint32_t)-1;
+
+static const flib_metascheme_setting metaSchemeSettings[] = {
+	{ .name = "damagefactor",      .times1000 = false, .engineCommand = "e$damagepct",   .maxMeansInfinity = false, .min = 10, .max = 300,  .def = 100 },
+	{ .name = "turntime",          .times1000 = true,  .engineCommand = "e$turntime",    .maxMeansInfinity = true,  .min = 1,  .max = 9999, .def = 45  },
+	{ .name = "health",            .times1000 = false, .engineCommand = NULL,            .maxMeansInfinity = false, .min = 50, .max = 200,  .def = 100 },
+	{ .name = "suddendeath",       .times1000 = false, .engineCommand = "e$sd_turns",    .maxMeansInfinity = true,  .min = 0,  .max = 50,   .def = 15  },
+	{ .name = "caseprobability",   .times1000 = false, .engineCommand = "e$casefreq",    .maxMeansInfinity = false, .min = 0,  .max = 9,    .def = 5   },
+	{ .name = "minestime",         .times1000 = true,  .engineCommand = "e$minestime",   .maxMeansInfinity = false, .min = -1, .max = 5,    .def = 3   },
+	{ .name = "minesnum",          .times1000 = false, .engineCommand = "e$minesnum",    .maxMeansInfinity = false, .min = 0,  .max = 80,   .def = 4   },
+	{ .name = "minedudpct",        .times1000 = false, .engineCommand = "e$minedudpct",  .maxMeansInfinity = false, .min = 0,  .max = 100,  .def = 0   },
+	{ .name = "explosives",        .times1000 = false, .engineCommand = "e$explosives",  .maxMeansInfinity = false, .min = 0,  .max = 40,   .def = 2   },
+	{ .name = "healthprobability", .times1000 = false, .engineCommand = "e$healthprob",  .maxMeansInfinity = false, .min = 0,  .max = 100,  .def = 35  },
+	{ .name = "healthcaseamount",  .times1000 = false, .engineCommand = "e$hcaseamount", .maxMeansInfinity = false, .min = 0,  .max = 200,  .def = 25  },
+	{ .name = "waterrise",         .times1000 = false, .engineCommand = "e$waterrise",   .maxMeansInfinity = false, .min = 0,  .max = 100,  .def = 47  },
+	{ .name = "healthdecrease",    .times1000 = false, .engineCommand = "e$healthdec",   .maxMeansInfinity = false, .min = 0,  .max = 100,  .def = 5   },
+	{ .name = "ropepct",           .times1000 = false, .engineCommand = "e$ropepct",     .maxMeansInfinity = false, .min = 25, .max = 999,  .def = 100 },
+	{ .name = "getawaytime",       .times1000 = false, .engineCommand = "e$getawaytime", .maxMeansInfinity = false, .min = 0,  .max = 999,  .def = 100 }
+};
+
+static const flib_metascheme_mod metaSchemeMods[] = {
+	{ .name = "fortsmode",          .bitmaskIndex = 12 },
+	{ .name = "divteams",           .bitmaskIndex = 4  },
+	{ .name = "solidland",          .bitmaskIndex = 2  },
+	{ .name = "border",             .bitmaskIndex = 3  },
+	{ .name = "lowgrav",            .bitmaskIndex = 5  },
+	{ .name = "laser",              .bitmaskIndex = 6  },
+	{ .name = "invulnerability",    .bitmaskIndex = 7  },
+	{ .name = "resethealth",        .bitmaskIndex = 8  },
+	{ .name = "vampiric",           .bitmaskIndex = 9  },
+	{ .name = "karma",              .bitmaskIndex = 10 },
+	{ .name = "artillery",          .bitmaskIndex = 11 },
+	{ .name = "randomorder",        .bitmaskIndex = 13 },
+	{ .name = "king",               .bitmaskIndex = 14 },
+	{ .name = "placehog",           .bitmaskIndex = 15 },
+	{ .name = "sharedammo",         .bitmaskIndex = 16 },
+	{ .name = "disablegirders",     .bitmaskIndex = 17 },
+	{ .name = "disablelandobjects", .bitmaskIndex = 18 },
+	{ .name = "aisurvival",         .bitmaskIndex = 19 },
+	{ .name = "infattack",          .bitmaskIndex = 20 },
+	{ .name = "resetweps",          .bitmaskIndex = 21 },
+	{ .name = "perhogammo",         .bitmaskIndex = 22 },
+	{ .name = "disablewind",        .bitmaskIndex = 23 },
+	{ .name = "morewind",           .bitmaskIndex = 24 },
+	{ .name = "tagteam",            .bitmaskIndex = 25 },
+	{ .name = "bottomborder",       .bitmaskIndex = 26 }
+};
+
+const flib_metascheme flib_meta = {
+	.settingCount = sizeof(metaSchemeSettings)/sizeof(flib_metascheme_setting),
+	.modCount = sizeof(metaSchemeMods)/sizeof(flib_metascheme_mod),
+	.settings = metaSchemeSettings,
+	.mods = metaSchemeMods
+};
+
+uint32_t flib_get_teamcolor(int colorIndex) {
+	if(colorIndex>=0 && colorIndex < flib_teamcolor_count) {
+		return flib_teamcolors[colorIndex];
+	} else {
+		return 0;
+	}
+}
+
+int flib_get_teamcolor_count() {
+	return flib_teamcolor_count;
+}
+
+int flib_get_hedgehogs_per_team() {
+	return HEDGEHOGS_PER_TEAM;
+}
+
+int flib_get_weapons_count() {
+	return WEAPONS_COUNT;
+}
+
+const flib_metascheme *flib_get_metascheme() {
+	return &flib_meta;
+}
diff --git a/project_files/frontlib/hwconsts.h b/project_files/frontlib/hwconsts.h
new file mode 100644
index 0000000..6c12248
--- /dev/null
+++ b/project_files/frontlib/hwconsts.h
@@ -0,0 +1,118 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2012 Simeon Maxein <smaxein at googlemail.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
+ */
+
+/**
+ * This file contains important constants which might need to be changed to adapt to
+ * changes in the engine or protocols.
+ *
+ * It also contains getter functions for some constants (in particular for constants
+ * that are important for the layout of data structures), so that client code can
+ * query the constants that the library was built with.
+ */
+
+#ifndef HWCONSTS_H_
+#define HWCONSTS_H_
+
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#define HEDGEHOGS_PER_TEAM 8
+#define DEFAULT_HEDGEHOG_COUNT 4
+#define DEFAULT_COLOR_INDEX 0
+
+#define NETGAME_DEFAULT_PORT 46631
+#define PROTOCOL_VERSION 42
+#define MIN_SERVER_VERSION 1
+
+//! Used for sending scripts to the engine
+#define MULTIPLAYER_SCRIPT_PATH "Scripts/Multiplayer/"
+
+#define WEAPONS_COUNT 56
+
+// TODO allow frontend to override these?
+/*! A merge of mikade/bugq colours w/ a bit of channel feedback */
+#define HW_TEAMCOLOR_ARRAY  { UINT32_C(0xffff0204), /*! red    */ \
+                              UINT32_C(0xff4980c1), /*! blue   */ \
+                              UINT32_C(0xff1de6ba), /*! teal   */ \
+                              UINT32_C(0xffb541ef), /*! purple */ \
+                              UINT32_C(0xffe55bb0), /*! pink   */ \
+                              UINT32_C(0xff20bf00), /*! green  */ \
+                              UINT32_C(0xfffe8b0e), /*! orange */ \
+                              UINT32_C(0xff5f3605), /*! brown  */ \
+                              UINT32_C(0xffffff01), /*! yellow */ \
+                              /*! add new colors here */ \
+                              0 } /*! Keep this 0 at the end */
+
+extern const size_t flib_teamcolor_count;
+extern const uint32_t flib_teamcolors[];
+
+/**
+ * Returns the team color (ARGB) corresponding to the color index (0 if index out of bounds)
+ */
+uint32_t flib_get_teamcolor(int colorIndex);
+
+/**
+ * Returns the number of team colors (i.e. the length of the flib_teamcolors array)
+ */
+int flib_get_teamcolor_count();
+
+/**
+ * Returns the HEDGEHOGS_PER_TEAM constant
+ */
+int flib_get_hedgehogs_per_team();
+
+/**
+ * Returns the WEAPONS_COUNT constant
+ */
+int flib_get_weapons_count();
+
+/*!
+ * These structs define the meaning of values in the flib_scheme struct, i.e. their correspondence to
+ * ini settings, engine commands and positions in the network protocol (the last is encoded in the
+ * order of settings/mods).
+ */
+typedef struct {
+    const char *name;				//!< A name identifying this setting (used as key in the schemes file)
+    const char *engineCommand;		//!< The command needed to send the setting to the engine. May be null if the setting is not sent to the engine (for the "health" setting)
+    const bool maxMeansInfinity;	//!< If true, send a very high number to the engine if the setting is equal to its maximum
+    const bool times1000;			//!< If true (for time-based settings), multiply the setting by 1000 before sending it to the engine.
+    const int min;					//!< The smallest allowed value
+    const int max;					//!< The highest allowed value
+    const int def;					//!< The default value
+} flib_metascheme_setting;
+
+typedef struct {
+    const char *name;				//!< A name identifying this mod (used as key in the schemes file)
+    const int bitmaskIndex;			//!< Mods are sent to the engine in a single integer, this field describes which bit of that integer is used
+    								//! for this particular mod.
+} flib_metascheme_mod;
+
+typedef struct {
+	const int settingCount;
+	const int modCount;
+	const flib_metascheme_setting *settings;
+	const flib_metascheme_mod *mods;
+} flib_metascheme;
+
+extern const flib_metascheme flib_meta;
+
+const flib_metascheme *flib_get_metascheme();
+
+#endif
diff --git a/project_files/frontlib/iniparser/LICENSE b/project_files/frontlib/iniparser/LICENSE
new file mode 100644
index 0000000..324a177
--- /dev/null
+++ b/project_files/frontlib/iniparser/LICENSE
@@ -0,0 +1,23 @@
+Copyright (c) 2000-2012 by Nicolas Devillard.
+MIT License
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/project_files/frontlib/iniparser/VERSION b/project_files/frontlib/iniparser/VERSION
new file mode 100644
index 0000000..3d60271
--- /dev/null
+++ b/project_files/frontlib/iniparser/VERSION
@@ -0,0 +1,2 @@
+This is version 3.1 of the iniparser library developed by N. Devillard.
+See http://ndevilla.free.fr/iniparser/ for details and new versions.
\ No newline at end of file
diff --git a/project_files/frontlib/iniparser/dictionary.c b/project_files/frontlib/iniparser/dictionary.c
new file mode 100644
index 0000000..3f0f5cf
--- /dev/null
+++ b/project_files/frontlib/iniparser/dictionary.c
@@ -0,0 +1,398 @@
+/*-------------------------------------------------------------------------*/
+/**
+   @file    dictionary.c
+   @author  N. Devillard
+   @brief   Implements a dictionary for string variables.
+
+   This module implements a simple dictionary object, i.e. a list
+   of string/string associations. This object is useful to store e.g.
+   informations retrieved from a configuration file (ini files).
+*/
+/*--------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+                                Includes
+ ---------------------------------------------------------------------------*/
+#include "dictionary.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/** Maximum value size for integers and doubles. */
+#define MAXVALSZ    1024
+
+/** Minimal allocated number of entries in a dictionary */
+#define DICTMINSZ   128
+
+/** Invalid key token */
+#define DICT_INVALID_KEY    ((char*)-1)
+
+/*---------------------------------------------------------------------------
+                            Private functions
+ ---------------------------------------------------------------------------*/
+
+/* Doubles the allocated size associated to a pointer */
+/* 'size' is the current allocated size. */
+static void * mem_double(void * ptr, int size)
+{
+    void * newptr ;
+ 
+    newptr = calloc(2*size, 1);
+    if (newptr==NULL) {
+        return NULL ;
+    }
+    memcpy(newptr, ptr, size);
+    free(ptr);
+    return newptr ;
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Duplicate a string
+  @param    s String to duplicate
+  @return   Pointer to a newly allocated string, to be freed with free()
+
+  This is a replacement for strdup(). This implementation is provided
+  for systems that do not have it.
+ */
+/*--------------------------------------------------------------------------*/
+static char * xstrdup(const char * s)
+{
+    char * t ;
+    if (!s)
+        return NULL ;
+    t = (char*)malloc(strlen(s)+1) ;
+    if (t) {
+        strcpy(t,s);
+    }
+    return t ;
+}
+
+/*---------------------------------------------------------------------------
+                            Function codes
+ ---------------------------------------------------------------------------*/
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Compute the hash key for a string.
+  @param    key     Character string to use for key.
+  @return   1 unsigned int on at least 32 bits.
+
+  This hash function has been taken from an Article in Dr Dobbs Journal.
+  This is normally a collision-free function, distributing keys evenly.
+  The key is stored anyway in the struct so that collision can be avoided
+  by comparing the key itself in last resort.
+ */
+/*--------------------------------------------------------------------------*/
+unsigned dictionary_hash(const char * key)
+{
+    int         len ;
+    unsigned    hash ;
+    int         i ;
+
+    len = strlen(key);
+    for (hash=0, i=0 ; i<len ; i++) {
+        hash += (unsigned)key[i] ;
+        hash += (hash<<10);
+        hash ^= (hash>>6) ;
+    }
+    hash += (hash <<3);
+    hash ^= (hash >>11);
+    hash += (hash <<15);
+    return hash ;
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Create a new dictionary object.
+  @param    size    Optional initial size of the dictionary.
+  @return   1 newly allocated dictionary objet.
+
+  This function allocates a new dictionary object of given size and returns
+  it. If you do not know in advance (roughly) the number of entries in the
+  dictionary, give size=0.
+ */
+/*--------------------------------------------------------------------------*/
+dictionary * dictionary_new(int size)
+{
+    dictionary  *   d ;
+
+    /* If no size was specified, allocate space for DICTMINSZ */
+    if (size<DICTMINSZ) size=DICTMINSZ ;
+
+    if (!(d = (dictionary *)calloc(1, sizeof(dictionary)))) {
+        return NULL;
+    }
+    d->size = size ;
+    d->val  = (char **)calloc(size, sizeof(char*));
+    d->key  = (char **)calloc(size, sizeof(char*));
+    d->hash = (unsigned int *)calloc(size, sizeof(unsigned));
+    return d ;
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Delete a dictionary object
+  @param    d   dictionary object to deallocate.
+  @return   void
+
+  Deallocate a dictionary object and all memory associated to it.
+ */
+/*--------------------------------------------------------------------------*/
+void dictionary_del(dictionary * d)
+{
+    int     i ;
+
+    if (d==NULL) return ;
+    for (i=0 ; i<d->size ; i++) {
+        if (d->key[i]!=NULL)
+            free(d->key[i]);
+        if (d->val[i]!=NULL)
+            free(d->val[i]);
+    }
+    free(d->val);
+    free(d->key);
+    free(d->hash);
+    free(d);
+    return ;
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Get a value from a dictionary.
+  @param    d       dictionary object to search.
+  @param    key     Key to look for in the dictionary.
+  @param    def     Default value to return if key not found.
+  @return   1 pointer to internally allocated character string.
+
+  This function locates a key in a dictionary and returns a pointer to its
+  value, or the passed 'def' pointer if no such key can be found in
+  dictionary. The returned character pointer points to data internal to the
+  dictionary object, you should not try to free it or modify it.
+ */
+/*--------------------------------------------------------------------------*/
+char * dictionary_get(dictionary * d, const char * key, char * def)
+{
+    unsigned    hash ;
+    int         i ;
+
+    hash = dictionary_hash(key);
+    for (i=0 ; i<d->size ; i++) {
+        if (d->key[i]==NULL)
+            continue ;
+        /* Compare hash */
+        if (hash==d->hash[i]) {
+            /* Compare string, to avoid hash collisions */
+            if (!strcmp(key, d->key[i])) {
+                return d->val[i] ;
+            }
+        }
+    }
+    return def ;
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Set a value in a dictionary.
+  @param    d       dictionary object to modify.
+  @param    key     Key to modify or add.
+  @param    val     Value to add.
+  @return   int     0 if Ok, anything else otherwise
+
+  If the given key is found in the dictionary, the associated value is
+  replaced by the provided one. If the key cannot be found in the
+  dictionary, it is added to it.
+
+  It is Ok to provide a NULL value for val, but NULL values for the dictionary
+  or the key are considered as errors: the function will return immediately
+  in such a case.
+
+  Notice that if you dictionary_set a variable to NULL, a call to
+  dictionary_get will return a NULL value: the variable will be found, and
+  its value (NULL) is returned. In other words, setting the variable
+  content to NULL is equivalent to deleting the variable from the
+  dictionary. It is not possible (in this implementation) to have a key in
+  the dictionary without value.
+
+  This function returns non-zero in case of failure.
+ */
+/*--------------------------------------------------------------------------*/
+int dictionary_set(dictionary * d, const char * key, const char * val)
+{
+    int         i ;
+    unsigned    hash ;
+
+    if (d==NULL || key==NULL) return -1 ;
+    
+    /* Compute hash for this key */
+    hash = dictionary_hash(key) ;
+    /* Find if value is already in dictionary */
+    if (d->n>0) {
+        for (i=0 ; i<d->size ; i++) {
+            if (d->key[i]==NULL)
+                continue ;
+            if (hash==d->hash[i]) { /* Same hash value */
+                if (!strcmp(key, d->key[i])) {   /* Same key */
+                    /* Found a value: modify and return */
+                    if (d->val[i]!=NULL)
+                        free(d->val[i]);
+                    d->val[i] = val ? xstrdup(val) : NULL ;
+                    /* Value has been modified: return */
+                    return 0 ;
+                }
+            }
+        }
+    }
+    /* Add a new value */
+    /* See if dictionary needs to grow */
+    if (d->n==d->size) {
+
+        /* Reached maximum size: reallocate dictionary */
+        d->val  = (char **)mem_double(d->val,  d->size * sizeof(char*)) ;
+        d->key  = (char **)mem_double(d->key,  d->size * sizeof(char*)) ;
+        d->hash = (unsigned int *)mem_double(d->hash, d->size * sizeof(unsigned)) ;
+        if ((d->val==NULL) || (d->key==NULL) || (d->hash==NULL)) {
+            /* Cannot grow dictionary */
+            return -1 ;
+        }
+        /* Double size */
+        d->size *= 2 ;
+    }
+
+    /* Insert key in the first empty slot. Start at d->n and wrap at
+       d->size. Because d->n < d->size this will necessarily
+       terminate. */
+    for (i=d->n ; d->key[i] ; ) {
+        if(++i == d->size) i = 0;
+    }
+    /* Copy key */
+    d->key[i]  = xstrdup(key);
+    d->val[i]  = val ? xstrdup(val) : NULL ;
+    d->hash[i] = hash;
+    d->n ++ ;
+    return 0 ;
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Delete a key in a dictionary
+  @param    d       dictionary object to modify.
+  @param    key     Key to remove.
+  @return   void
+
+  This function deletes a key in a dictionary. Nothing is done if the
+  key cannot be found.
+ */
+/*--------------------------------------------------------------------------*/
+void dictionary_unset(dictionary * d, const char * key)
+{
+    unsigned    hash ;
+    int         i ;
+
+    if (key == NULL) {
+        return;
+    }
+
+    hash = dictionary_hash(key);
+    for (i=0 ; i<d->size ; i++) {
+        if (d->key[i]==NULL)
+            continue ;
+        /* Compare hash */
+        if (hash==d->hash[i]) {
+            /* Compare string, to avoid hash collisions */
+            if (!strcmp(key, d->key[i])) {
+                /* Found key */
+                break ;
+            }
+        }
+    }
+    if (i>=d->size)
+        /* Key not found */
+        return ;
+
+    free(d->key[i]);
+    d->key[i] = NULL ;
+    if (d->val[i]!=NULL) {
+        free(d->val[i]);
+        d->val[i] = NULL ;
+    }
+    d->hash[i] = 0 ;
+    d->n -- ;
+    return ;
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Dump a dictionary to an opened file pointer.
+  @param    d   Dictionary to dump
+  @param    f   Opened file pointer.
+  @return   void
+
+  Dumps a dictionary onto an opened file pointer. Key pairs are printed out
+  as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as
+  output file pointers.
+ */
+/*--------------------------------------------------------------------------*/
+void dictionary_dump(dictionary * d, FILE * out)
+{
+    int     i ;
+
+    if (d==NULL || out==NULL) return ;
+    if (d->n<1) {
+        fprintf(out, "empty dictionary\n");
+        return ;
+    }
+    for (i=0 ; i<d->size ; i++) {
+        if (d->key[i]) {
+            fprintf(out, "%20s\t[%s]\n",
+                    d->key[i],
+                    d->val[i] ? d->val[i] : "UNDEF");
+        }
+    }
+    return ;
+}
+
+
+/* Test code */
+#ifdef TESTDIC
+#define NVALS 20000
+int main(int argc, char *argv[])
+{
+    dictionary  *   d ;
+    char    *   val ;
+    int         i ;
+    char        cval[90] ;
+
+    /* Allocate dictionary */
+    printf("allocating...\n");
+    d = dictionary_new(0);
+    
+    /* Set values in dictionary */
+    printf("setting %d values...\n", NVALS);
+    for (i=0 ; i<NVALS ; i++) {
+        sprintf(cval, "%04d", i);
+        dictionary_set(d, cval, "salut");
+    }
+    printf("getting %d values...\n", NVALS);
+    for (i=0 ; i<NVALS ; i++) {
+        sprintf(cval, "%04d", i);
+        val = dictionary_get(d, cval, DICT_INVALID_KEY);
+        if (val==DICT_INVALID_KEY) {
+            printf("cannot get value for key [%s]\n", cval);
+        }
+    }
+    printf("unsetting %d values...\n", NVALS);
+    for (i=0 ; i<NVALS ; i++) {
+        sprintf(cval, "%04d", i);
+        dictionary_unset(d, cval);
+    }
+    if (d->n != 0) {
+        printf("error deleting values\n");
+    }
+    printf("deallocating...\n");
+    dictionary_del(d);
+    return 0 ;
+}
+#endif
+/* vim: set ts=4 et sw=4 tw=75 */
diff --git a/project_files/frontlib/iniparser/dictionary.h b/project_files/frontlib/iniparser/dictionary.h
new file mode 100644
index 0000000..34c4b82
--- /dev/null
+++ b/project_files/frontlib/iniparser/dictionary.h
@@ -0,0 +1,165 @@
+
+/*-------------------------------------------------------------------------*/
+/**
+   @file    dictionary.h
+   @author  N. Devillard
+   @brief   Implements a dictionary for string variables.
+
+   This module implements a simple dictionary object, i.e. a list
+   of string/string associations. This object is useful to store e.g.
+   informations retrieved from a configuration file (ini files).
+*/
+/*--------------------------------------------------------------------------*/
+
+#ifndef _DICTIONARY_H_
+#define _DICTIONARY_H_
+
+/*---------------------------------------------------------------------------
+                                Includes
+ ---------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/*---------------------------------------------------------------------------
+                                New types
+ ---------------------------------------------------------------------------*/
+
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Dictionary object
+
+  This object contains a list of string/string associations. Each
+  association is identified by a unique string key. Looking up values
+  in the dictionary is speeded up by the use of a (hopefully collision-free)
+  hash function.
+ */
+/*-------------------------------------------------------------------------*/
+typedef struct _dictionary_ {
+    int             n ;     /** Number of entries in dictionary */
+    int             size ;  /** Storage size */
+    char        **  val ;   /** List of string values */
+    char        **  key ;   /** List of string keys */
+    unsigned     *  hash ;  /** List of hash values for keys */
+} dictionary ;
+
+
+/*---------------------------------------------------------------------------
+                            Function prototypes
+ ---------------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Compute the hash key for a string.
+  @param    key     Character string to use for key.
+  @return   1 unsigned int on at least 32 bits.
+
+  This hash function has been taken from an Article in Dr Dobbs Journal.
+  This is normally a collision-free function, distributing keys evenly.
+  The key is stored anyway in the struct so that collision can be avoided
+  by comparing the key itself in last resort.
+ */
+/*--------------------------------------------------------------------------*/
+unsigned dictionary_hash(const char * key);
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Create a new dictionary object.
+  @param    size    Optional initial size of the dictionary.
+  @return   1 newly allocated dictionary objet.
+
+  This function allocates a new dictionary object of given size and returns
+  it. If you do not know in advance (roughly) the number of entries in the
+  dictionary, give size=0.
+ */
+/*--------------------------------------------------------------------------*/
+dictionary * dictionary_new(int size);
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Delete a dictionary object
+  @param    d   dictionary object to deallocate.
+  @return   void
+
+  Deallocate a dictionary object and all memory associated to it.
+ */
+/*--------------------------------------------------------------------------*/
+void dictionary_del(dictionary * vd);
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Get a value from a dictionary.
+  @param    d       dictionary object to search.
+  @param    key     Key to look for in the dictionary.
+  @param    def     Default value to return if key not found.
+  @return   1 pointer to internally allocated character string.
+
+  This function locates a key in a dictionary and returns a pointer to its
+  value, or the passed 'def' pointer if no such key can be found in
+  dictionary. The returned character pointer points to data internal to the
+  dictionary object, you should not try to free it or modify it.
+ */
+/*--------------------------------------------------------------------------*/
+char * dictionary_get(dictionary * d, const char * key, char * def);
+
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Set a value in a dictionary.
+  @param    d       dictionary object to modify.
+  @param    key     Key to modify or add.
+  @param    val     Value to add.
+  @return   int     0 if Ok, anything else otherwise
+
+  If the given key is found in the dictionary, the associated value is
+  replaced by the provided one. If the key cannot be found in the
+  dictionary, it is added to it.
+
+  It is Ok to provide a NULL value for val, but NULL values for the dictionary
+  or the key are considered as errors: the function will return immediately
+  in such a case.
+
+  Notice that if you dictionary_set a variable to NULL, a call to
+  dictionary_get will return a NULL value: the variable will be found, and
+  its value (NULL) is returned. In other words, setting the variable
+  content to NULL is equivalent to deleting the variable from the
+  dictionary. It is not possible (in this implementation) to have a key in
+  the dictionary without value.
+
+  This function returns non-zero in case of failure.
+ */
+/*--------------------------------------------------------------------------*/
+int dictionary_set(dictionary * vd, const char * key, const char * val);
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Delete a key in a dictionary
+  @param    d       dictionary object to modify.
+  @param    key     Key to remove.
+  @return   void
+
+  This function deletes a key in a dictionary. Nothing is done if the
+  key cannot be found.
+ */
+/*--------------------------------------------------------------------------*/
+void dictionary_unset(dictionary * d, const char * key);
+
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Dump a dictionary to an opened file pointer.
+  @param    d   Dictionary to dump
+  @param    f   Opened file pointer.
+  @return   void
+
+  Dumps a dictionary onto an opened file pointer. Key pairs are printed out
+  as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as
+  output file pointers.
+ */
+/*--------------------------------------------------------------------------*/
+void dictionary_dump(dictionary * d, FILE * out);
+
+#endif
diff --git a/project_files/frontlib/iniparser/iniparser.c b/project_files/frontlib/iniparser/iniparser.c
new file mode 100644
index 0000000..d557955
--- /dev/null
+++ b/project_files/frontlib/iniparser/iniparser.c
@@ -0,0 +1,748 @@
+
+/*-------------------------------------------------------------------------*/
+/**
+   @file    iniparser.c
+   @author  N. Devillard
+   @brief   Parser for ini files.
+*/
+/*--------------------------------------------------------------------------*/
+/*---------------------------- Includes ------------------------------------*/
+#include <ctype.h>
+#include "iniparser.h"
+
+/*---------------------------- Defines -------------------------------------*/
+#define ASCIILINESZ         (1024)
+#define INI_INVALID_KEY     ((char*)-1)
+
+/*---------------------------------------------------------------------------
+                        Private to this module
+ ---------------------------------------------------------------------------*/
+/**
+ * This enum stores the status for each parsed line (internal use only).
+ */
+typedef enum _line_status_ {
+    LINE_UNPROCESSED,
+    LINE_ERROR,
+    LINE_EMPTY,
+    LINE_COMMENT,
+    LINE_SECTION,
+    LINE_VALUE
+} line_status ;
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Convert a string to lowercase.
+  @param    s   String to convert.
+  @return   ptr to statically allocated string.
+
+  This function returns a pointer to a statically allocated string
+  containing a lowercased version of the input string. Do not free
+  or modify the returned string! Since the returned string is statically
+  allocated, it will be modified at each function call (not re-entrant).
+ */
+/*--------------------------------------------------------------------------*/
+static char * strlwc(const char * s)
+{
+    static char l[ASCIILINESZ+1];
+    int i ;
+
+    if (s==NULL) return NULL ;
+    memset(l, 0, ASCIILINESZ+1);
+    i=0 ;
+    while (s[i] && i<ASCIILINESZ) {
+        l[i] = (char)tolower((int)s[i]);
+        i++ ;
+    }
+    l[ASCIILINESZ]=(char)0;
+    return l ;
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Remove blanks at the beginning and the end of a string.
+  @param    s   String to parse.
+  @return   ptr to statically allocated string.
+
+  This function returns a pointer to a statically allocated string,
+  which is identical to the input string, except that all blank
+  characters at the end and the beg. of the string have been removed.
+  Do not free or modify the returned string! Since the returned string
+  is statically allocated, it will be modified at each function call
+  (not re-entrant).
+ */
+/*--------------------------------------------------------------------------*/
+static char * strstrip(const char * s)
+{
+    static char l[ASCIILINESZ+1];
+    char * last ;
+    
+    if (s==NULL) return NULL ;
+    
+    while (isspace((int)*s) && *s) s++;
+    memset(l, 0, ASCIILINESZ+1);
+    strcpy(l, s);
+    last = l + strlen(l);
+    while (last > l) {
+        if (!isspace((int)*(last-1)))
+            break ;
+        last -- ;
+    }
+    *last = (char)0;
+    return (char*)l ;
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Get number of sections in a dictionary
+  @param    d   Dictionary to examine
+  @return   int Number of sections found in dictionary
+
+  This function returns the number of sections found in a dictionary.
+  The test to recognize sections is done on the string stored in the
+  dictionary: a section name is given as "section" whereas a key is
+  stored as "section:key", thus the test looks for entries that do not
+  contain a colon.
+
+  This clearly fails in the case a section name contains a colon, but
+  this should simply be avoided.
+
+  This function returns -1 in case of error.
+ */
+/*--------------------------------------------------------------------------*/
+int iniparser_getnsec(dictionary * d)
+{
+    int i ;
+    int nsec ;
+
+    if (d==NULL) return -1 ;
+    nsec=0 ;
+    for (i=0 ; i<d->size ; i++) {
+        if (d->key[i]==NULL)
+            continue ;
+        if (strchr(d->key[i], ':')==NULL) {
+            nsec ++ ;
+        }
+    }
+    return nsec ;
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Get name for section n in a dictionary.
+  @param    d   Dictionary to examine
+  @param    n   Section number (from 0 to nsec-1).
+  @return   Pointer to char string
+
+  This function locates the n-th section in a dictionary and returns
+  its name as a pointer to a string statically allocated inside the
+  dictionary. Do not free or modify the returned string!
+
+  This function returns NULL in case of error.
+ */
+/*--------------------------------------------------------------------------*/
+char * iniparser_getsecname(dictionary * d, int n)
+{
+    int i ;
+    int foundsec ;
+
+    if (d==NULL || n<0) return NULL ;
+    foundsec=0 ;
+    for (i=0 ; i<d->size ; i++) {
+        if (d->key[i]==NULL)
+            continue ;
+        if (strchr(d->key[i], ':')==NULL) {
+            foundsec++ ;
+            if (foundsec>n)
+                break ;
+        }
+    }
+    if (foundsec<=n) {
+        return NULL ;
+    }
+    return d->key[i] ;
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Dump a dictionary to an opened file pointer.
+  @param    d   Dictionary to dump.
+  @param    f   Opened file pointer to dump to.
+  @return   void
+
+  This function prints out the contents of a dictionary, one element by
+  line, onto the provided file pointer. It is OK to specify @c stderr
+  or @c stdout as output files. This function is meant for debugging
+  purposes mostly.
+ */
+/*--------------------------------------------------------------------------*/
+void iniparser_dump(dictionary * d, FILE * f)
+{
+    int     i ;
+
+    if (d==NULL || f==NULL) return ;
+    for (i=0 ; i<d->size ; i++) {
+        if (d->key[i]==NULL)
+            continue ;
+        if (d->val[i]!=NULL) {
+            fprintf(f, "[%s]=[%s]\n", d->key[i], d->val[i]);
+        } else {
+            fprintf(f, "[%s]=UNDEF\n", d->key[i]);
+        }
+    }
+    return ;
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Save a dictionary to a loadable ini file
+  @param    d   Dictionary to dump
+  @param    f   Opened file pointer to dump to
+  @return   void
+
+  This function dumps a given dictionary into a loadable ini file.
+  It is Ok to specify @c stderr or @c stdout as output files.
+ */
+/*--------------------------------------------------------------------------*/
+void iniparser_dump_ini(dictionary * d, FILE * f)
+{
+    int     i ;
+    int     nsec ;
+    char *  secname ;
+
+    if (d==NULL || f==NULL) return ;
+
+    nsec = iniparser_getnsec(d);
+    if (nsec<1) {
+        /* No section in file: dump all keys as they are */
+        for (i=0 ; i<d->size ; i++) {
+            if (d->key[i]==NULL)
+                continue ;
+            fprintf(f, "%s = %s\n", d->key[i], d->val[i]);
+        }
+        return ;
+    }
+    for (i=0 ; i<nsec ; i++) {
+        secname = iniparser_getsecname(d, i) ;
+        iniparser_dumpsection_ini(d, secname, f) ;
+    }
+    fprintf(f, "\n");
+    return ;
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Save a dictionary section to a loadable ini file
+  @param    d   Dictionary to dump
+  @param    s   Section name of dictionary to dump
+  @param    f   Opened file pointer to dump to
+  @return   void
+
+  This function dumps a given section of a given dictionary into a loadable ini
+  file.  It is Ok to specify @c stderr or @c stdout as output files.
+ */
+/*--------------------------------------------------------------------------*/
+void iniparser_dumpsection_ini(dictionary * d, char * s, FILE * f)
+{
+    int     j ;
+    char    keym[ASCIILINESZ+1];
+    int     seclen ;
+
+    if (d==NULL || f==NULL) return ;
+    if (! iniparser_find_entry(d, s)) return ;
+
+    seclen  = (int)strlen(s);
+    fprintf(f, "\n[%s]\n", s);
+    sprintf(keym, "%s:", s);
+    for (j=0 ; j<d->size ; j++) {
+        if (d->key[j]==NULL)
+            continue ;
+        if (!strncmp(d->key[j], keym, seclen+1)) {
+            fprintf(f,
+                    "%-30s = %s\n",
+                    d->key[j]+seclen+1,
+                    d->val[j] ? d->val[j] : "");
+        }
+    }
+    fprintf(f, "\n");
+    return ;
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Get the number of keys in a section of a dictionary.
+  @param    d   Dictionary to examine
+  @param    s   Section name of dictionary to examine
+  @return   Number of keys in section
+ */
+/*--------------------------------------------------------------------------*/
+int iniparser_getsecnkeys(dictionary * d, char * s)
+{
+    int     seclen, nkeys ;
+    char    keym[ASCIILINESZ+1];
+    int j ;
+
+    nkeys = 0;
+
+    if (d==NULL) return nkeys;
+    if (! iniparser_find_entry(d, s)) return nkeys;
+
+    seclen  = (int)strlen(s);
+    sprintf(keym, "%s:", s);
+
+    for (j=0 ; j<d->size ; j++) {
+        if (d->key[j]==NULL)
+            continue ;
+        if (!strncmp(d->key[j], keym, seclen+1)) 
+            nkeys++;
+    }
+
+    return nkeys;
+
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Get the number of keys in a section of a dictionary.
+  @param    d   Dictionary to examine
+  @param    s   Section name of dictionary to examine
+  @return   pointer to statically allocated character strings
+
+  This function queries a dictionary and finds all keys in a given section.
+  Each pointer in the returned char pointer-to-pointer is pointing to
+  a string allocated in the dictionary; do not free or modify them.
+  
+  This function returns NULL in case of error.
+ */
+/*--------------------------------------------------------------------------*/
+char ** iniparser_getseckeys(dictionary * d, char * s)
+{
+
+    char **keys;
+
+    int i, j ;
+    char    keym[ASCIILINESZ+1];
+    int     seclen, nkeys ;
+
+    keys = NULL;
+
+    if (d==NULL) return keys;
+    if (! iniparser_find_entry(d, s)) return keys;
+
+    nkeys = iniparser_getsecnkeys(d, s);
+
+    keys = (char**) malloc(nkeys*sizeof(char*));
+
+    seclen  = (int)strlen(s);
+    sprintf(keym, "%s:", s);
+    
+    i = 0;
+
+    for (j=0 ; j<d->size ; j++) {
+        if (d->key[j]==NULL)
+            continue ;
+        if (!strncmp(d->key[j], keym, seclen+1)) {
+            keys[i] = d->key[j];
+            i++;
+        }
+    }
+
+    return keys;
+
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Get the string associated to a key
+  @param    d       Dictionary to search
+  @param    key     Key string to look for
+  @param    def     Default value to return if key not found.
+  @return   pointer to statically allocated character string
+
+  This function queries a dictionary for a key. A key as read from an
+  ini file is given as "section:key". If the key cannot be found,
+  the pointer passed as 'def' is returned.
+  The returned char pointer is pointing to a string allocated in
+  the dictionary, do not free or modify it.
+ */
+/*--------------------------------------------------------------------------*/
+char * iniparser_getstring(dictionary * d, const char * key, char * def)
+{
+    char * lc_key ;
+    char * sval ;
+
+    if (d==NULL || key==NULL)
+        return def ;
+
+    lc_key = strlwc(key);
+    sval = dictionary_get(d, lc_key, def);
+    return sval ;
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Get the string associated to a key, convert to an int
+  @param    d Dictionary to search
+  @param    key Key string to look for
+  @param    notfound Value to return in case of error
+  @return   integer
+
+  This function queries a dictionary for a key. A key as read from an
+  ini file is given as "section:key". If the key cannot be found,
+  the notfound value is returned.
+
+  Supported values for integers include the usual C notation
+  so decimal, octal (starting with 0) and hexadecimal (starting with 0x)
+  are supported. Examples:
+
+  "42"      ->  42
+  "042"     ->  34 (octal -> decimal)
+  "0x42"    ->  66 (hexa  -> decimal)
+
+  Warning: the conversion may overflow in various ways. Conversion is
+  totally outsourced to strtol(), see the associated man page for overflow
+  handling.
+
+  Credits: Thanks to A. Becker for suggesting strtol()
+ */
+/*--------------------------------------------------------------------------*/
+int iniparser_getint(dictionary * d, const char * key, int notfound)
+{
+    char    *   str ;
+
+    str = iniparser_getstring(d, key, INI_INVALID_KEY);
+    if (str==INI_INVALID_KEY) return notfound ;
+    return (int)strtol(str, NULL, 0);
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Get the string associated to a key, convert to a double
+  @param    d Dictionary to search
+  @param    key Key string to look for
+  @param    notfound Value to return in case of error
+  @return   double
+
+  This function queries a dictionary for a key. A key as read from an
+  ini file is given as "section:key". If the key cannot be found,
+  the notfound value is returned.
+ */
+/*--------------------------------------------------------------------------*/
+double iniparser_getdouble(dictionary * d, const char * key, double notfound)
+{
+    char    *   str ;
+
+    str = iniparser_getstring(d, key, INI_INVALID_KEY);
+    if (str==INI_INVALID_KEY) return notfound ;
+    return atof(str);
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Get the string associated to a key, convert to a boolean
+  @param    d Dictionary to search
+  @param    key Key string to look for
+  @param    notfound Value to return in case of error
+  @return   integer
+
+  This function queries a dictionary for a key. A key as read from an
+  ini file is given as "section:key". If the key cannot be found,
+  the notfound value is returned.
+
+  A true boolean is found if one of the following is matched:
+
+  - A string starting with 'y'
+  - A string starting with 'Y'
+  - A string starting with 't'
+  - A string starting with 'T'
+  - A string starting with '1'
+
+  A false boolean is found if one of the following is matched:
+
+  - A string starting with 'n'
+  - A string starting with 'N'
+  - A string starting with 'f'
+  - A string starting with 'F'
+  - A string starting with '0'
+
+  The notfound value returned if no boolean is identified, does not
+  necessarily have to be 0 or 1.
+ */
+/*--------------------------------------------------------------------------*/
+int iniparser_getboolean(dictionary * d, const char * key, int notfound)
+{
+    char    *   c ;
+    int         ret ;
+
+    c = iniparser_getstring(d, key, INI_INVALID_KEY);
+    if (c==INI_INVALID_KEY) return notfound ;
+    if (c[0]=='y' || c[0]=='Y' || c[0]=='1' || c[0]=='t' || c[0]=='T') {
+        ret = 1 ;
+    } else if (c[0]=='n' || c[0]=='N' || c[0]=='0' || c[0]=='f' || c[0]=='F') {
+        ret = 0 ;
+    } else {
+        ret = notfound ;
+    }
+    return ret;
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Finds out if a given entry exists in a dictionary
+  @param    ini     Dictionary to search
+  @param    entry   Name of the entry to look for
+  @return   integer 1 if entry exists, 0 otherwise
+
+  Finds out if a given entry exists in the dictionary. Since sections
+  are stored as keys with NULL associated values, this is the only way
+  of querying for the presence of sections in a dictionary.
+ */
+/*--------------------------------------------------------------------------*/
+int iniparser_find_entry(
+    dictionary  *   ini,
+    const char  *   entry
+)
+{
+    int found=0 ;
+    if (iniparser_getstring(ini, entry, INI_INVALID_KEY)!=INI_INVALID_KEY) {
+        found = 1 ;
+    }
+    return found ;
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Set an entry in a dictionary.
+  @param    ini     Dictionary to modify.
+  @param    entry   Entry to modify (entry name)
+  @param    val     New value to associate to the entry.
+  @return   int 0 if Ok, -1 otherwise.
+
+  If the given entry can be found in the dictionary, it is modified to
+  contain the provided value. If it cannot be found, -1 is returned.
+  It is Ok to set val to NULL.
+ */
+/*--------------------------------------------------------------------------*/
+int iniparser_set(dictionary * ini, const char * entry, const char * val)
+{
+    return dictionary_set(ini, strlwc(entry), val) ;
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Delete an entry in a dictionary
+  @param    ini     Dictionary to modify
+  @param    entry   Entry to delete (entry name)
+  @return   void
+
+  If the given entry can be found, it is deleted from the dictionary.
+ */
+/*--------------------------------------------------------------------------*/
+void iniparser_unset(dictionary * ini, const char * entry)
+{
+    dictionary_unset(ini, strlwc(entry));
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Load a single line from an INI file
+  @param    input_line  Input line, may be concatenated multi-line input
+  @param    section     Output space to store section
+  @param    key         Output space to store key
+  @param    value       Output space to store value
+  @return   line_status value
+ */
+/*--------------------------------------------------------------------------*/
+static line_status iniparser_line(
+    const char * input_line,
+    char * section,
+    char * key,
+    char * value)
+{   
+    line_status sta ;
+    char        line[ASCIILINESZ+1];
+    int         len ;
+
+    strcpy(line, strstrip(input_line));
+    len = (int)strlen(line);
+
+    sta = LINE_UNPROCESSED ;
+    if (len<1) {
+        /* Empty line */
+        sta = LINE_EMPTY ;
+    } else if (line[0]=='#' || line[0]==';') {
+        /* Comment line */
+        sta = LINE_COMMENT ; 
+    } else if (line[0]=='[' && line[len-1]==']') {
+        /* Section name */
+        sscanf(line, "[%[^]]", section);
+        strcpy(section, strstrip(section));
+        strcpy(section, strlwc(section));
+        sta = LINE_SECTION ;
+    } else if (sscanf (line, "%[^=] = \"%[^\"]\"", key, value) == 2
+           ||  sscanf (line, "%[^=] = '%[^\']'",   key, value) == 2
+           ||  sscanf (line, "%[^=] = %[^;#]",     key, value) == 2) {
+        /* Usual key=value, with or without comments */
+        strcpy(key, strstrip(key));
+        strcpy(key, strlwc(key));
+        strcpy(value, strstrip(value));
+        /*
+         * sscanf cannot handle '' or "" as empty values
+         * this is done here
+         */
+        if (!strcmp(value, "\"\"") || (!strcmp(value, "''"))) {
+            value[0]=0 ;
+        }
+        sta = LINE_VALUE ;
+    } else if (sscanf(line, "%[^=] = %[;#]", key, value)==2
+           ||  sscanf(line, "%[^=] %[=]", key, value) == 2) {
+        /*
+         * Special cases:
+         * key=
+         * key=;
+         * key=#
+         */
+        strcpy(key, strstrip(key));
+        strcpy(key, strlwc(key));
+        value[0]=0 ;
+        sta = LINE_VALUE ;
+    } else {
+        /* Generate syntax error */
+        sta = LINE_ERROR ;
+    }
+    return sta ;
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Parse an ini file and return an allocated dictionary object
+  @param    ininame Name of the ini file to read.
+  @return   Pointer to newly allocated dictionary
+
+  This is the parser for ini files. This function is called, providing
+  the name of the file to be read. It returns a dictionary object that
+  should not be accessed directly, but through accessor functions
+  instead.
+
+  The returned dictionary must be freed using iniparser_freedict().
+ */
+/*--------------------------------------------------------------------------*/
+dictionary * iniparser_load(const char * ininame)
+{
+    FILE * in ;
+
+    char line    [ASCIILINESZ+1] ;
+    char section [ASCIILINESZ+1] ;
+    char key     [ASCIILINESZ+1] ;
+    char tmp     [ASCIILINESZ+1] ;
+    char val     [ASCIILINESZ+1] ;
+
+    int  last=0 ;
+    int  len ;
+    int  lineno=0 ;
+    int  errs=0;
+
+    dictionary * dict ;
+
+    if ((in=fopen(ininame, "r"))==NULL) {
+        fprintf(stderr, "iniparser: cannot open %s\n", ininame);
+        return NULL ;
+    }
+
+    dict = dictionary_new(0) ;
+    if (!dict) {
+        fclose(in);
+        return NULL ;
+    }
+
+    memset(line,    0, ASCIILINESZ);
+    memset(section, 0, ASCIILINESZ);
+    memset(key,     0, ASCIILINESZ);
+    memset(val,     0, ASCIILINESZ);
+    last=0 ;
+
+    while (fgets(line+last, ASCIILINESZ-last, in)!=NULL) {
+        lineno++ ;
+        len = (int)strlen(line)-1;
+        if (len==0)
+            continue;
+        /* Safety check against buffer overflows */
+        if (line[len]!='\n') {
+            fprintf(stderr,
+                    "iniparser: input line too long in %s (%d)\n",
+                    ininame,
+                    lineno);
+            dictionary_del(dict);
+            fclose(in);
+            return NULL ;
+        }
+        /* Get rid of \n and spaces at end of line */
+        while ((len>=0) &&
+                ((line[len]=='\n') || (isspace(line[len])))) {
+            line[len]=0 ;
+            len-- ;
+        }
+        /* Detect multi-line */
+        if (line[len]=='\\') {
+            /* Multi-line value */
+            last=len ;
+            continue ;
+        } else {
+            last=0 ;
+        }
+        switch (iniparser_line(line, section, key, val)) {
+            case LINE_EMPTY:
+            case LINE_COMMENT:
+            break ;
+
+            case LINE_SECTION:
+            errs = dictionary_set(dict, section, NULL);
+            break ;
+
+            case LINE_VALUE:
+            sprintf(tmp, "%s:%s", section, key);
+            errs = dictionary_set(dict, tmp, val) ;
+            break ;
+
+            case LINE_ERROR:
+            fprintf(stderr, "iniparser: syntax error in %s (%d):\n",
+                    ininame,
+                    lineno);
+            fprintf(stderr, "-> %s\n", line);
+            errs++ ;
+            break;
+
+            default:
+            break ;
+        }
+        memset(line, 0, ASCIILINESZ);
+        last=0;
+        if (errs<0) {
+            fprintf(stderr, "iniparser: memory allocation failure\n");
+            break ;
+        }
+    }
+    if (errs) {
+        dictionary_del(dict);
+        dict = NULL ;
+    }
+    fclose(in);
+    return dict ;
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Free all memory associated to an ini dictionary
+  @param    d Dictionary to free
+  @return   void
+
+  Free all memory associated to an ini dictionary.
+  It is mandatory to call this function before the dictionary object
+  gets out of the current context.
+ */
+/*--------------------------------------------------------------------------*/
+void iniparser_freedict(dictionary * d)
+{
+    dictionary_del(d);
+}
+
+/* vim: set ts=4 et sw=4 tw=75 */
diff --git a/project_files/frontlib/iniparser/iniparser.h b/project_files/frontlib/iniparser/iniparser.h
new file mode 100644
index 0000000..ecd73bf
--- /dev/null
+++ b/project_files/frontlib/iniparser/iniparser.h
@@ -0,0 +1,307 @@
+
+/*-------------------------------------------------------------------------*/
+/**
+   @file    iniparser.h
+   @author  N. Devillard
+   @brief   Parser for ini files.
+*/
+/*--------------------------------------------------------------------------*/
+
+#ifndef _INIPARSER_H_
+#define _INIPARSER_H_
+
+/*---------------------------------------------------------------------------
+                                Includes
+ ---------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * The following #include is necessary on many Unixes but not Linux.
+ * It is not needed for Windows platforms.
+ * Uncomment it if needed.
+ */
+/* #include <unistd.h> */
+
+#include "dictionary.h"
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Get number of sections in a dictionary
+  @param    d   Dictionary to examine
+  @return   int Number of sections found in dictionary
+
+  This function returns the number of sections found in a dictionary.
+  The test to recognize sections is done on the string stored in the
+  dictionary: a section name is given as "section" whereas a key is
+  stored as "section:key", thus the test looks for entries that do not
+  contain a colon.
+
+  This clearly fails in the case a section name contains a colon, but
+  this should simply be avoided.
+
+  This function returns -1 in case of error.
+ */
+/*--------------------------------------------------------------------------*/
+
+int iniparser_getnsec(dictionary * d);
+
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Get name for section n in a dictionary.
+  @param    d   Dictionary to examine
+  @param    n   Section number (from 0 to nsec-1).
+  @return   Pointer to char string
+
+  This function locates the n-th section in a dictionary and returns
+  its name as a pointer to a string statically allocated inside the
+  dictionary. Do not free or modify the returned string!
+
+  This function returns NULL in case of error.
+ */
+/*--------------------------------------------------------------------------*/
+
+char * iniparser_getsecname(dictionary * d, int n);
+
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Save a dictionary to a loadable ini file
+  @param    d   Dictionary to dump
+  @param    f   Opened file pointer to dump to
+  @return   void
+
+  This function dumps a given dictionary into a loadable ini file.
+  It is Ok to specify @c stderr or @c stdout as output files.
+ */
+/*--------------------------------------------------------------------------*/
+
+void iniparser_dump_ini(dictionary * d, FILE * f);
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Save a dictionary section to a loadable ini file
+  @param    d   Dictionary to dump
+  @param    s   Section name of dictionary to dump
+  @param    f   Opened file pointer to dump to
+  @return   void
+
+  This function dumps a given section of a given dictionary into a loadable ini
+  file.  It is Ok to specify @c stderr or @c stdout as output files.
+ */
+/*--------------------------------------------------------------------------*/
+
+void iniparser_dumpsection_ini(dictionary * d, char * s, FILE * f);
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Dump a dictionary to an opened file pointer.
+  @param    d   Dictionary to dump.
+  @param    f   Opened file pointer to dump to.
+  @return   void
+
+  This function prints out the contents of a dictionary, one element by
+  line, onto the provided file pointer. It is OK to specify @c stderr
+  or @c stdout as output files. This function is meant for debugging
+  purposes mostly.
+ */
+/*--------------------------------------------------------------------------*/
+void iniparser_dump(dictionary * d, FILE * f);
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Get the number of keys in a section of a dictionary.
+  @param    d   Dictionary to examine
+  @param    s   Section name of dictionary to examine
+  @return   Number of keys in section
+ */
+/*--------------------------------------------------------------------------*/
+int iniparser_getsecnkeys(dictionary * d, char * s);
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Get the number of keys in a section of a dictionary.
+  @param    d   Dictionary to examine
+  @param    s   Section name of dictionary to examine
+  @return   pointer to statically allocated character strings
+
+  This function queries a dictionary and finds all keys in a given section.
+  Each pointer in the returned char pointer-to-pointer is pointing to
+  a string allocated in the dictionary; do not free or modify them.
+
+  This function returns NULL in case of error.
+ */
+/*--------------------------------------------------------------------------*/
+char ** iniparser_getseckeys(dictionary * d, char * s);
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Get the string associated to a key
+  @param    d       Dictionary to search
+  @param    key     Key string to look for
+  @param    def     Default value to return if key not found.
+  @return   pointer to statically allocated character string
+
+  This function queries a dictionary for a key. A key as read from an
+  ini file is given as "section:key". If the key cannot be found,
+  the pointer passed as 'def' is returned.
+  The returned char pointer is pointing to a string allocated in
+  the dictionary, do not free or modify it.
+ */
+/*--------------------------------------------------------------------------*/
+char * iniparser_getstring(dictionary * d, const char * key, char * def);
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Get the string associated to a key, convert to an int
+  @param    d Dictionary to search
+  @param    key Key string to look for
+  @param    notfound Value to return in case of error
+  @return   integer
+
+  This function queries a dictionary for a key. A key as read from an
+  ini file is given as "section:key". If the key cannot be found,
+  the notfound value is returned.
+
+  Supported values for integers include the usual C notation
+  so decimal, octal (starting with 0) and hexadecimal (starting with 0x)
+  are supported. Examples:
+
+  - "42"      ->  42
+  - "042"     ->  34 (octal -> decimal)
+  - "0x42"    ->  66 (hexa  -> decimal)
+
+  Warning: the conversion may overflow in various ways. Conversion is
+  totally outsourced to strtol(), see the associated man page for overflow
+  handling.
+
+  Credits: Thanks to A. Becker for suggesting strtol()
+ */
+/*--------------------------------------------------------------------------*/
+int iniparser_getint(dictionary * d, const char * key, int notfound);
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Get the string associated to a key, convert to a double
+  @param    d Dictionary to search
+  @param    key Key string to look for
+  @param    notfound Value to return in case of error
+  @return   double
+
+  This function queries a dictionary for a key. A key as read from an
+  ini file is given as "section:key". If the key cannot be found,
+  the notfound value is returned.
+ */
+/*--------------------------------------------------------------------------*/
+double iniparser_getdouble(dictionary * d, const char * key, double notfound);
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Get the string associated to a key, convert to a boolean
+  @param    d Dictionary to search
+  @param    key Key string to look for
+  @param    notfound Value to return in case of error
+  @return   integer
+
+  This function queries a dictionary for a key. A key as read from an
+  ini file is given as "section:key". If the key cannot be found,
+  the notfound value is returned.
+
+  A true boolean is found if one of the following is matched:
+
+  - A string starting with 'y'
+  - A string starting with 'Y'
+  - A string starting with 't'
+  - A string starting with 'T'
+  - A string starting with '1'
+
+  A false boolean is found if one of the following is matched:
+
+  - A string starting with 'n'
+  - A string starting with 'N'
+  - A string starting with 'f'
+  - A string starting with 'F'
+  - A string starting with '0'
+
+  The notfound value returned if no boolean is identified, does not
+  necessarily have to be 0 or 1.
+ */
+/*--------------------------------------------------------------------------*/
+int iniparser_getboolean(dictionary * d, const char * key, int notfound);
+
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Set an entry in a dictionary.
+  @param    ini     Dictionary to modify.
+  @param    entry   Entry to modify (entry name)
+  @param    val     New value to associate to the entry.
+  @return   int 0 if Ok, -1 otherwise.
+
+  If the given entry can be found in the dictionary, it is modified to
+  contain the provided value. If it cannot be found, -1 is returned.
+  It is Ok to set val to NULL.
+ */
+/*--------------------------------------------------------------------------*/
+int iniparser_set(dictionary * ini, const char * entry, const char * val);
+
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Delete an entry in a dictionary
+  @param    ini     Dictionary to modify
+  @param    entry   Entry to delete (entry name)
+  @return   void
+
+  If the given entry can be found, it is deleted from the dictionary.
+ */
+/*--------------------------------------------------------------------------*/
+void iniparser_unset(dictionary * ini, const char * entry);
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Finds out if a given entry exists in a dictionary
+  @param    ini     Dictionary to search
+  @param    entry   Name of the entry to look for
+  @return   integer 1 if entry exists, 0 otherwise
+
+  Finds out if a given entry exists in the dictionary. Since sections
+  are stored as keys with NULL associated values, this is the only way
+  of querying for the presence of sections in a dictionary.
+ */
+/*--------------------------------------------------------------------------*/
+int iniparser_find_entry(dictionary * ini, const char * entry) ;
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Parse an ini file and return an allocated dictionary object
+  @param    ininame Name of the ini file to read.
+  @return   Pointer to newly allocated dictionary
+
+  This is the parser for ini files. This function is called, providing
+  the name of the file to be read. It returns a dictionary object that
+  should not be accessed directly, but through accessor functions
+  instead.
+
+  The returned dictionary must be freed using iniparser_freedict().
+ */
+/*--------------------------------------------------------------------------*/
+dictionary * iniparser_load(const char * ininame);
+
+/*-------------------------------------------------------------------------*/
+/**
+  @brief    Free all memory associated to an ini dictionary
+  @param    d Dictionary to free
+  @return   void
+
+  Free all memory associated to an ini dictionary.
+  It is mandatory to call this function before the dictionary object
+  gets out of the current context.
+ */
+/*--------------------------------------------------------------------------*/
+void iniparser_freedict(dictionary * d);
+
+#endif
diff --git a/project_files/frontlib/ipc/gameconn.c b/project_files/frontlib/ipc/gameconn.c
new file mode 100644
index 0000000..0931993
--- /dev/null
+++ b/project_files/frontlib/ipc/gameconn.c
@@ -0,0 +1,452 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "gameconn.h"
+#include "ipcbase.h"
+#include "ipcprotocol.h"
+#include "../util/logging.h"
+#include "../util/util.h"
+#include "../hwconsts.h"
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef enum {
+	AWAIT_CONNECTION,
+	CONNECTED,
+	FINISHED
+} gameconn_state;
+
+struct _flib_gameconn {
+	flib_ipcbase *ipcBase;
+	flib_vector *configBuffer;
+	flib_vector *demoBuffer;
+	char *playerName;
+
+	gameconn_state state;
+	bool netgame;
+	int disconnectReason;
+
+	void (*onConnectCb)(void* context);
+	void *onConnectCtx;
+
+	void (*onDisconnectCb)(void* context, int reason);
+	void *onDisconnectCtx;
+
+	void (*onErrorMessageCb)(void* context, const char *msg);
+	void *onErrorMessageCtx;
+
+	void (*onChatCb)(void* context, const char *msg, bool teamchat);
+	void *onChatCtx;
+
+	void (*onGameRecordedCb)(void *context, const uint8_t *record, size_t size, bool isSavegame);
+	void *onGameRecordedCtx;
+
+	void (*onEngineMessageCb)(void *context, const uint8_t *em, size_t size);
+	void *onEngineMessageCtx;
+
+	bool running;
+	bool destroyRequested;
+};
+
+static void defaultCallback_onErrorMessage(void* context, const char *msg) {
+	flib_log_w("Error from engine (no callback set): %s", msg);
+}
+
+static void clearCallbacks(flib_gameconn *conn) {
+	flib_gameconn_onConnect(conn, NULL, NULL);
+	flib_gameconn_onDisconnect(conn, NULL, NULL);
+	flib_gameconn_onErrorMessage(conn, NULL, NULL);
+	flib_gameconn_onChat(conn, NULL, NULL);
+	flib_gameconn_onGameRecorded(conn, NULL, NULL);
+	flib_gameconn_onEngineMessage(conn, NULL, NULL);
+}
+
+static flib_gameconn *flib_gameconn_create_partial(bool record, const char *playerName, bool netGame) {
+	flib_gameconn *result = NULL;
+	flib_gameconn *tempConn = flib_calloc(1, sizeof(flib_gameconn));
+	if(tempConn) {
+		tempConn->ipcBase = flib_ipcbase_create();
+		tempConn->configBuffer = flib_vector_create();
+		tempConn->playerName = flib_strdupnull(playerName);
+		if(tempConn->ipcBase && tempConn->configBuffer && tempConn->playerName) {
+			if(record) {
+				tempConn->demoBuffer = flib_vector_create();
+			}
+			tempConn->state = AWAIT_CONNECTION;
+			tempConn->netgame = netGame;
+			tempConn->disconnectReason = GAME_END_ERROR;
+			clearCallbacks(tempConn);
+			result = tempConn;
+			tempConn = NULL;
+		}
+	}
+	flib_gameconn_destroy(tempConn);
+	return result;
+}
+
+flib_gameconn *flib_gameconn_create(const char *playerName, const flib_gamesetup *setup, bool netgame) {
+	if(log_badargs_if2(playerName==NULL, setup==NULL)) {
+		return NULL;
+	}
+	flib_gameconn *result = NULL;
+	flib_gameconn *tempConn = flib_gameconn_create_partial(true, playerName, netgame);
+	if(tempConn) {
+		if(flib_ipc_append_fullconfig(tempConn->configBuffer, setup, netgame)) {
+			flib_log_e("Error generating full game configuration for the engine.");
+		} else {
+			result = tempConn;
+			tempConn = NULL;
+		}
+	}
+	flib_gameconn_destroy(tempConn);
+	return result;
+}
+
+flib_gameconn *flib_gameconn_create_playdemo(const uint8_t *demoFileContent, size_t size) {
+	if(log_badargs_if(demoFileContent==NULL && size>0)) {
+		return NULL;
+	}
+	flib_gameconn *result = NULL;
+	flib_gameconn *tempConn = flib_gameconn_create_partial(false, "Player", false);
+	if(tempConn) {
+		if(!flib_vector_append(tempConn->configBuffer, demoFileContent, size)) {
+			result = tempConn;
+			tempConn = NULL;
+		}
+	}
+	flib_gameconn_destroy(tempConn);
+	return result;
+}
+
+flib_gameconn *flib_gameconn_create_loadgame(const char *playerName, const uint8_t *saveFileContent, size_t size) {
+	if(log_badargs_if(saveFileContent==NULL && size>0)) {
+		return NULL;
+	}
+	flib_gameconn *result = NULL;
+	flib_gameconn *tempConn = flib_gameconn_create_partial(true, playerName, false);
+	if(tempConn) {
+		if(!flib_vector_append(tempConn->configBuffer, saveFileContent, size)) {
+			result = tempConn;
+			tempConn = NULL;
+		}
+	}
+	flib_gameconn_destroy(tempConn);
+	return result;
+}
+
+flib_gameconn *flib_gameconn_create_campaign(const char *playerName, const char *seed, const char *script) {
+	if(log_badargs_if3(playerName==NULL, seed==NULL, script==NULL)) {
+		return NULL;
+	}
+	flib_gameconn *result = NULL;
+	flib_gameconn *tempConn = flib_gameconn_create_partial(true, playerName, false);
+	if(tempConn) {
+		if(!flib_ipc_append_message(tempConn->configBuffer, "TL")
+				&& !flib_ipc_append_seed(tempConn->configBuffer, seed)
+				&& !flib_ipc_append_script(tempConn->configBuffer, script)
+				&& !flib_ipc_append_message(tempConn->configBuffer, "!")) {
+			result = tempConn;
+			tempConn = NULL;
+		}
+	}
+	flib_gameconn_destroy(tempConn);
+	return result;
+}
+
+void flib_gameconn_destroy(flib_gameconn *conn) {
+	if(conn) {
+		if(conn->running) {
+			/*
+			 * The function was called from a callback, so the tick function is still running
+			 * and we delay the actual destruction. We ensure no further callbacks will be
+			 * sent to prevent surprises.
+			 */
+			clearCallbacks(conn);
+			conn->destroyRequested = true;
+		} else {
+			flib_ipcbase_destroy(conn->ipcBase);
+			flib_vector_destroy(conn->configBuffer);
+			flib_vector_destroy(conn->demoBuffer);
+			free(conn->playerName);
+			free(conn);
+		}
+	}
+}
+
+int flib_gameconn_getport(flib_gameconn *conn) {
+	if(log_badargs_if(conn==NULL)) {
+		return 0;
+	}
+	return flib_ipcbase_port(conn->ipcBase);
+}
+
+static void demo_append(flib_gameconn *conn, const void *data, size_t len) {
+	if(conn->demoBuffer) {
+		if(flib_vector_append(conn->demoBuffer, data, len)) {
+			flib_log_e("Error recording demo: Out of memory.");
+			flib_vector_destroy(conn->demoBuffer);
+			conn->demoBuffer = NULL;
+		}
+	}
+}
+
+static int format_chatmessage(uint8_t buffer[257], const char *playerName, const char *message) {
+	size_t msglen = strlen(message);
+
+	// If the message starts with /me, it will be displayed differently.
+	bool meMessage = msglen >= 4 && !memcmp(message, "/me ", 4);
+	const char *template = meMessage ? "s\x02* %s %s  " : "s\x01%s: %s  ";
+	int size = snprintf((char*)buffer+1, 256, template, playerName, meMessage ? message+4 : message);
+	if(log_e_if(size<=0, "printf error")) {
+		return -1;
+	} else {
+		buffer[0] = size>255 ? 255 : size;
+		return 0;
+	}
+}
+
+static void demo_append_chatmessage(flib_gameconn *conn, const char *message) {
+	// Chat messages are reformatted to make them look as if they were received, not sent.
+	uint8_t converted[257];
+	if(!format_chatmessage(converted, conn->playerName, message)) {
+		demo_append(conn, converted, converted[0]+1);
+	}
+}
+
+static void demo_replace_gamemode(flib_buffer buf, char gamemode) {
+	size_t msgStart = 0;
+	uint8_t *data = (uint8_t*)buf.data;
+	while(msgStart+2 < buf.size) {
+		if(!memcmp(data+msgStart, "\x02T", 2)) {
+			data[msgStart+2] = gamemode;
+		}
+		msgStart += (uint8_t)data[msgStart]+1;
+	}
+}
+
+int flib_gameconn_send_enginemsg(flib_gameconn *conn, const uint8_t *data, size_t len) {
+	if(log_badargs_if2(conn==NULL, data==NULL && len>0)) {
+		return -1;
+	}
+	int result = flib_ipcbase_send_raw(conn->ipcBase, data, len);
+	if(!result) {
+		demo_append(conn, data, len);
+	}
+	return result;
+}
+
+int flib_gameconn_send_textmsg(flib_gameconn *conn, int msgtype, const char *msg) {
+	if(log_badargs_if2(conn==NULL, msg==NULL)) {
+		return -1;
+	}
+	int result = -1;
+	uint8_t converted[257];
+	int size = snprintf((char*)converted+1, 256, "s%c%s", (char)msgtype, msg);
+	if(size>0) {
+		converted[0] = size>255 ? 255 : size;
+		if(!flib_ipcbase_send_raw(conn->ipcBase, converted, converted[0]+1)) {
+			demo_append(conn, converted, converted[0]+1);
+			result = 0;
+		}
+	}
+	return result;
+}
+
+int flib_gameconn_send_chatmsg(flib_gameconn *conn, const char *playername, const char *msg) {
+	if(log_badargs_if3(conn==NULL, playername==NULL, msg==NULL)) {
+		return -1;
+	}
+	uint8_t converted[257];
+	if(!format_chatmessage(converted, playername, msg)
+			&& !flib_ipcbase_send_raw(conn->ipcBase, converted, converted[0]+1)) {
+		demo_append(conn, converted, converted[0]+1);
+		return 0;
+	}
+	return -1;
+}
+
+int flib_gameconn_send_quit(flib_gameconn *conn) {
+	return flib_gameconn_send_cmd(conn, "efinish");
+}
+
+int flib_gameconn_send_cmd(flib_gameconn *conn, const char *cmdString) {
+	if(log_badargs_if2(conn==NULL, cmdString==NULL)) {
+		return -1;
+	}
+	int result = -1;
+	uint8_t converted[256];
+	size_t msglen = strlen(cmdString);
+	if(!log_e_if(msglen>255, "Message too long: %s", cmdString)) {
+		strcpy((char*)converted+1, cmdString);
+		converted[0] = msglen;
+		if(!flib_ipcbase_send_raw(conn->ipcBase, converted, msglen+1)) {
+			demo_append(conn, converted, msglen+1);
+			result = 0;
+		}
+	}
+	return result;
+}
+
+/**
+ * This macro generates a callback setter function. It uses the name of the callback to
+ * automatically generate the function name and the fields to set, so a consistent naming
+ * convention needs to be enforced (not that that is a bad thing). If null is passed as
+ * callback to the generated function, the defaultCb will be set instead (with conn
+ * as the context).
+ */
+#define GENERATE_CB_SETTER(cbName, cbParameterTypes, defaultCb) \
+	void flib_gameconn_##cbName(flib_gameconn *conn, void (*callback)cbParameterTypes, void *context) { \
+		if(!log_badargs_if(conn==NULL)) { \
+			conn->cbName##Cb = callback ? callback : &defaultCb; \
+			conn->cbName##Ctx = callback ? context : conn; \
+		} \
+	}
+
+/**
+ * Generate a callback setter function like GENERATE_CB_SETTER, and automatically generate a
+ * no-op callback function as well that is used as default.
+ */
+#define GENERATE_CB_SETTER_AND_DEFAULT(cbName, cbParameterTypes) \
+	static void _noop_callback_##cbName cbParameterTypes {} \
+	GENERATE_CB_SETTER(cbName, cbParameterTypes, _noop_callback_##cbName)
+
+GENERATE_CB_SETTER_AND_DEFAULT(onConnect, (void *context));
+GENERATE_CB_SETTER_AND_DEFAULT(onDisconnect, (void* context, int reason));
+GENERATE_CB_SETTER(onErrorMessage, (void* context, const char *msg), defaultCallback_onErrorMessage);
+GENERATE_CB_SETTER_AND_DEFAULT(onChat, (void* context, const char *msg, bool teamchat));
+GENERATE_CB_SETTER_AND_DEFAULT(onGameRecorded, (void *context, const uint8_t *record, size_t size, bool isSavegame));
+GENERATE_CB_SETTER_AND_DEFAULT(onEngineMessage, (void *context, const uint8_t *em, size_t size));
+
+#undef GENERATE_CB_SETTER_AND_DEFAULT
+#undef GENERATE_CB_SETTER
+
+static void flib_gameconn_wrappedtick(flib_gameconn *conn) {
+	if(conn->state == AWAIT_CONNECTION) {
+		flib_ipcbase_accept(conn->ipcBase);
+		switch(flib_ipcbase_state(conn->ipcBase)) {
+		case IPC_CONNECTED:
+			{
+				flib_constbuffer configBuffer = flib_vector_as_constbuffer(conn->configBuffer);
+				if(flib_ipcbase_send_raw(conn->ipcBase, configBuffer.data, configBuffer.size)) {
+					conn->state = FINISHED;
+					conn->onDisconnectCb(conn->onDisconnectCtx, GAME_END_ERROR);
+					return;
+				} else {
+					demo_append(conn, configBuffer.data, configBuffer.size);
+					conn->state = CONNECTED;
+					conn->onConnectCb(conn->onConnectCtx);
+					if(conn->destroyRequested) {
+						return;
+					}
+				}
+			}
+			break;
+		case IPC_NOT_CONNECTED:
+			conn->state = FINISHED;
+			conn->onDisconnectCb(conn->onDisconnectCtx, GAME_END_ERROR);
+			return;
+		default:
+			break;
+		}
+	}
+
+	if(conn->state == CONNECTED) {
+		uint8_t msgbuffer[257];
+		int len;
+		while(!conn->destroyRequested && (len = flib_ipcbase_recv_message(conn->ipcBase, msgbuffer))>=0) {
+			if(len<2) {
+				flib_log_w("Received short message from IPC (<2 bytes)");
+				continue;
+			}
+			switch(msgbuffer[1]) {
+			case '?':	// Ping
+				// The pong is already part of the config message
+				break;
+			case 'C':	// Config query
+				// And we already send the config message on connecting.
+				break;
+			case 'E':	// Error message
+				if(len>=3) {
+					msgbuffer[len-2] = 0;
+					conn->onErrorMessageCb(conn->onErrorMessageCtx, (char*)msgbuffer+2);
+				}
+				break;
+			case 'i':	// Statistics
+				// TODO stats
+				break;
+			case 'Q':	// Game interrupted
+			case 'H':	// Game halted
+			case 'q':	// game finished
+				{
+					int reason = msgbuffer[1]=='Q' ? GAME_END_INTERRUPTED : msgbuffer[1]=='H' ? GAME_END_HALTED : GAME_END_FINISHED;
+					conn->disconnectReason = reason;
+					bool savegame = (reason != GAME_END_FINISHED) && !conn->netgame;
+					if(conn->demoBuffer) {
+						flib_buffer demoBuffer = flib_vector_as_buffer(conn->demoBuffer);
+						demo_replace_gamemode(demoBuffer, savegame ? 'S' : 'D');
+						conn->onGameRecordedCb(conn->onGameRecordedCtx, demoBuffer.data, demoBuffer.size, savegame);
+						if(conn->destroyRequested) {
+							return;
+						}
+					}
+					return;
+				}
+			case 's':	// Chat message
+				if(len>=3) {
+					msgbuffer[len-2] = 0;
+					demo_append_chatmessage(conn, (char*)msgbuffer+2);
+
+					conn->onChatCb(conn->onChatCtx, (char*)msgbuffer+2, false);
+				}
+				break;
+			case 'b':	// Teamchat message
+				if(len>=3) {
+					msgbuffer[len-2] = 0;
+					conn->onChatCb(conn->onChatCtx, (char*)msgbuffer+2, true);
+				}
+				break;
+			default:	// Engine message
+				demo_append(conn, msgbuffer, len);
+
+				conn->onEngineMessageCb(conn->onEngineMessageCtx, msgbuffer, len);
+				break;
+			}
+		}
+	}
+
+	if(flib_ipcbase_state(conn->ipcBase) == IPC_NOT_CONNECTED) {
+		conn->state = FINISHED;
+		conn->onDisconnectCb(conn->onDisconnectCtx, conn->disconnectReason);
+	}
+}
+
+void flib_gameconn_tick(flib_gameconn *conn) {
+	if(!log_badargs_if(conn == NULL)
+			&& !log_w_if(conn->running, "Call to flib_gameconn_tick from a callback")
+			&& !log_w_if(conn->state == FINISHED, "We are already done.")) {
+		conn->running = true;
+		flib_gameconn_wrappedtick(conn);
+		conn->running = false;
+
+		if(conn->destroyRequested) {
+			flib_gameconn_destroy(conn);
+		}
+	}
+}
diff --git a/project_files/frontlib/ipc/gameconn.h b/project_files/frontlib/ipc/gameconn.h
new file mode 100644
index 0000000..7f89e5a
--- /dev/null
+++ b/project_files/frontlib/ipc/gameconn.h
@@ -0,0 +1,179 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/**
+ * This file contains functions for starting and interacting with a game run by the engine.
+ * The general usage is to first create a gameconn object by calling one of the flib_gameconn_create
+ * functions. That will cause the frontlib to listen on a random port which can be queried using
+ * flib_gameconn_getport(). You should also register your callback functions right at the start
+ * to ensure you don't miss any callbacks.
+ *
+ * Next, start the engine (that part is up to you) with the appropriate command line arguments
+ * for starting a game.
+ *
+ * In order to allow the gameconn to run, you should regularly call flib_gameconn_tick(), which
+ * performs network I/O and calls your callbacks on interesting events.
+ *
+ * Once the engine connects, the gameconn will send it the required commands for starting the
+ * game you requested in your flib_gameconn_create call.
+ *
+ * When the game is finished (or the connection is lost), you will receive the onDisconnect
+ * message. This is the signal to destroy the gameconn and stop calling tick().
+ */
+
+#ifndef GAMECONN_H_
+#define GAMECONN_H_
+
+#include "../model/gamesetup.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+/*
+ * Different reasons for a disconnect. Only GAME_END_FINISHED signals a correctly completed game.
+ */
+#define GAME_END_FINISHED 0
+#define GAME_END_INTERRUPTED 1
+#define GAME_END_HALTED 2
+#define GAME_END_ERROR 3
+
+typedef struct _flib_gameconn flib_gameconn;
+
+/**
+ * Create a gameconn that will start a local or network game with the indicated configuration.
+ */
+flib_gameconn *flib_gameconn_create(const char *playerName, const flib_gamesetup *setup, bool netgame);
+
+/**
+ * Create a gameconn that will play back a demo.
+ */
+flib_gameconn *flib_gameconn_create_playdemo(const uint8_t *demoFileContent, size_t size);
+
+/**
+ * Create a gameconn that will continue from a saved game.
+ */
+flib_gameconn *flib_gameconn_create_loadgame(const char *playerName, const uint8_t *saveFileContent, size_t size);
+
+/**
+ * Create a gameconn that will start a campaign or training mission with the indicated script.
+ * seed is the random seed to use as entropy source (any string).
+ * script is the path and filename of a Campaign or Training script, relative to the Data directory
+ * (e.g. "Missions/Training/Basic_Training_-_Bazooka.lua")
+ */
+flib_gameconn *flib_gameconn_create_campaign(const char *playerName, const char *seed, const char *script);
+
+/**
+ * Release all resources of this gameconn, including the network connection, and free its memory.
+ * It is safe to call this function from a callback.
+ */
+void flib_gameconn_destroy(flib_gameconn *conn);
+
+/**
+ * Returns the port on which the gameconn is listening. Only fails if you
+ * pass NULL (not allowed), in that case 0 is returned.
+ */
+int flib_gameconn_getport(flib_gameconn *conn);
+
+/**
+ * Perform I/O operations and call callbacks if something interesting happens.
+ * Should be called regularly.
+ */
+void flib_gameconn_tick(flib_gameconn *conn);
+
+/**
+ * Send an engine message to the engine. Only needed in net games, where you receive engine
+ * messages from the server and have to pass them here.
+ */
+int flib_gameconn_send_enginemsg(flib_gameconn *conn, const uint8_t *data, size_t len);
+
+/**
+ * Send an info message to the engine that will be displayed in the game's chatlog.
+ * The msgtype determines the color of the message;  in the QTFrontend, info messages and
+ * normal chat messages use 1, emote-messages (those starting with /me) use 2, and
+ * join/leave messages use 3. You should use flib_gameconn_send_chatmsg for chat messages
+ * though because it automatically formats /me messages.
+ *
+ * Generally only needed in net games.
+ */
+int flib_gameconn_send_textmsg(flib_gameconn *conn, int msgtype, const char *msg);
+
+/**
+ * Send a chat message to be displayed in the game's chatlog. Messages starting with /me are
+ * automatically formatted correctly.
+ *
+ * Generally only needed in net games.
+ */
+int flib_gameconn_send_chatmsg(flib_gameconn *conn, const char *playername, const char *msg);
+
+/**
+ * Request the engine to stop the game (efinish).
+ * You can use this to shut down a game early without directly killing the engine process.
+ */
+int flib_gameconn_send_quit(flib_gameconn *conn);
+
+/**
+ * Send an arbitrary command to the engine, e.g. "eforcequit" to shut down the engine
+ * quickly. Commands prefixed with "e" will be processed by the engine's ProcessCommand
+ * method (with the e removed, so e.g. efinish will be parsed as finish).
+ */
+int flib_gameconn_send_cmd(flib_gameconn *conn, const char *cmdString);
+
+/**
+ * Expected callback signature: void handleConnect(void *context)
+ * The engine has successfully connected. You don't have to react to this in any way.
+ */
+void flib_gameconn_onConnect(flib_gameconn *conn, void (*callback)(void* context), void* context);
+
+/**
+ * Expected callback signature: void handleDisconnect(void *context, int reason)
+ * The connection to the engine was closed, either because the game has ended normally, or
+ * because it was interrupted/halted, or because of an error. The reason is provided as one
+ * of the GAME_END_xxx constants.
+ *
+ * You should destroy the gameconn and - in a netgame - notify the server that the game has ended.
+ */
+void flib_gameconn_onDisconnect(flib_gameconn *conn, void (*callback)(void* context, int reason), void* context);
+
+/**
+ * Expected callback signature: void handleErrorMessage(void* context, const char *msg)
+ * The engine sent an error message, you should probably display it to the user or at least log it.
+ */
+void flib_gameconn_onErrorMessage(flib_gameconn *conn, void (*callback)(void* context, const char *msg), void* context);
+
+/**
+ * Expected callback signature: void handleChat(void* context, const char *msg, bool teamchat)
+ * The player entered a chat or teamchat message. In a netgame, you should send it on to the server.
+ */
+void flib_gameconn_onChat(flib_gameconn *conn, void (*callback)(void* context, const char *msg, bool teamchat), void* context);
+
+/**
+ * Expected callback signature: void handleGameRecorded(void *context, const uint8_t *record, size_t size, bool isSavegame)
+ * The game has stopped, and a demo or savegame is available. You can store it in a file and later pass it back
+ * to the engine to either watch a replay (if it's a demo) or to continue playing (if it's a savegame).
+ */
+void flib_gameconn_onGameRecorded(flib_gameconn *conn, void (*callback)(void *context, const uint8_t *record, size_t size, bool isSavegame), void* context);
+
+/**
+ * Expected callback signature: void handleEngineMessage(void *context, const uint8_t *em, size_t size)
+ * The engine has generated a message with player input. In a netgame, you should send it on to the server.
+ */
+void flib_gameconn_onEngineMessage(flib_gameconn *conn, void (*callback)(void *context, const uint8_t *em, size_t size), void* context);
+
+#endif
diff --git a/project_files/frontlib/ipc/ipcbase.c b/project_files/frontlib/ipc/ipcbase.c
new file mode 100644
index 0000000..ab5419b
--- /dev/null
+++ b/project_files/frontlib/ipc/ipcbase.c
@@ -0,0 +1,216 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "ipcbase.h"
+#include "../util/logging.h"
+#include "../util/util.h"
+#include "../socket.h"
+
+#include <string.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+/*
+ * The receive buffer has to be able to hold any message that might be received. Normally
+ * the messages are at most 256 bytes, but the map preview contains 4097 bytes (4096 for a
+ * bitmap, 1 for the number of hogs which fit on the map).
+ *
+ * We don't need to worry about wasting a few kb though, and I like powers of two...
+ */
+struct _flib_ipcbase {
+	uint8_t readBuffer[8192];
+	int readBufferSize;
+
+	flib_acceptor *acceptor;
+	uint16_t port;
+
+	flib_tcpsocket *sock;
+};
+
+flib_ipcbase *flib_ipcbase_create() {
+	flib_ipcbase *result = flib_calloc(1, sizeof(flib_ipcbase));
+	flib_acceptor *acceptor = flib_acceptor_create(0);
+
+	if(!result || !acceptor) {
+		free(result);
+		flib_acceptor_close(acceptor);
+		return NULL;
+	}
+
+	result->acceptor = acceptor;
+	result->sock = NULL;
+	result->readBufferSize = 0;
+	result->port = flib_acceptor_listenport(acceptor);
+
+	flib_log_i("Started listening for IPC connections on port %u", (unsigned)result->port);
+	return result;
+}
+
+uint16_t flib_ipcbase_port(flib_ipcbase *ipc) {
+	if(log_badargs_if(ipc==NULL)) {
+		return 0;
+	}
+	return ipc->port;
+}
+
+void flib_ipcbase_destroy(flib_ipcbase *ipc) {
+	if(ipc) {
+		flib_acceptor_close(ipc->acceptor);
+		flib_socket_close(ipc->sock);
+		if(ipc->sock) {
+			flib_log_d("IPC connection closed.");
+		}
+		free(ipc);
+	}
+}
+
+IpcState flib_ipcbase_state(flib_ipcbase *ipc) {
+	if(log_badargs_if(ipc==NULL)) {
+		return IPC_NOT_CONNECTED;
+	} else if(ipc->sock) {
+		return IPC_CONNECTED;
+	} else if(ipc->acceptor) {
+		return IPC_LISTENING;
+	} else {
+		return IPC_NOT_CONNECTED;
+	}
+}
+
+static void receiveToBuffer(flib_ipcbase *ipc) {
+	if(ipc->sock) {
+		int size = flib_socket_nbrecv(ipc->sock, ipc->readBuffer+ipc->readBufferSize, sizeof(ipc->readBuffer)-ipc->readBufferSize);
+		if(size>=0) {
+			ipc->readBufferSize += size;
+		} else {
+			flib_log_d("IPC connection lost.");
+			flib_socket_close(ipc->sock);
+			ipc->sock = NULL;
+		}
+	}
+}
+
+static bool isMessageReady(flib_ipcbase *ipc) {
+	return ipc->readBufferSize >= ipc->readBuffer[0]+1;
+}
+
+static void logSentMsg(const uint8_t *data, size_t len) {
+	if(flib_log_isActive(FLIB_LOGLEVEL_DEBUG)) {
+		size_t msgStart = 0;
+		while(msgStart < len) {
+			uint8_t msglen = data[msgStart];
+			if(msgStart+msglen < len) {
+				flib_log_d("[IPC OUT][%03u]%*.*s",(unsigned)msglen, (unsigned)msglen, (unsigned)msglen, data+msgStart+1);
+			} else {
+				uint8_t msglen2 = len-msgStart-1;
+				flib_log_d("[IPC OUT][%03u/%03u]%*.*s",(unsigned)msglen2, (unsigned)msglen, (unsigned)msglen2, (unsigned)msglen2, data+msgStart+1);
+			}
+			msgStart += (uint8_t)data[msgStart]+1;
+		}
+	}
+}
+
+static void logRecvMsg(const uint8_t *data) {
+	if(flib_log_isActive(FLIB_LOGLEVEL_DEBUG)) {
+		uint8_t msglen = data[0];
+		flib_log_d("[IPC IN][%03u]%*.*s",(unsigned)msglen, (unsigned)msglen, (unsigned)msglen, data+1);
+	}
+}
+
+static void popFromReadBuffer(flib_ipcbase *ipc, uint8_t *outbuf, size_t size) {
+	memcpy(outbuf, ipc->readBuffer, size);
+	memmove(ipc->readBuffer, ipc->readBuffer+size, ipc->readBufferSize-size);
+	ipc->readBufferSize -= size;
+}
+
+int flib_ipcbase_recv_message(flib_ipcbase *ipc, void *data) {
+	if(log_badargs_if2(ipc==NULL, data==NULL)) {
+		return -1;
+	}
+
+	if(!isMessageReady(ipc)) {
+		receiveToBuffer(ipc);
+	}
+
+	if(isMessageReady(ipc)) {
+		int msgsize = ipc->readBuffer[0]+1;
+		popFromReadBuffer(ipc, data, msgsize);
+		logRecvMsg(data);
+		return msgsize;
+	} else if(!ipc->sock && ipc->readBufferSize>0) {
+		flib_log_w("Last message from engine data stream is incomplete (received %u of %u bytes)", (unsigned)ipc->readBufferSize, (unsigned)(ipc->readBuffer[0])+1);
+		ipc->readBufferSize = 0;
+		return -1;
+	} else {
+		return -1;
+	}
+}
+
+int flib_ipcbase_recv_map(flib_ipcbase *ipc, void *data) {
+	if(log_badargs_if2(ipc==NULL, data==NULL)) {
+		return -1;
+	}
+
+	receiveToBuffer(ipc);
+
+	if(ipc->readBufferSize >= IPCBASE_MAPMSG_BYTES) {
+		popFromReadBuffer(ipc, data, IPCBASE_MAPMSG_BYTES);
+		return IPCBASE_MAPMSG_BYTES;
+	} else {
+		return -1;
+	}
+}
+
+int flib_ipcbase_send_raw(flib_ipcbase *ipc, const void *data, size_t len) {
+	if(log_badargs_if2(ipc==NULL, data==NULL && len>0)
+			|| log_w_if(!ipc->sock, "flib_ipcbase_send_raw: Not connected.")) {
+		return -1;
+	}
+	if(flib_socket_send(ipc->sock, data, len) == len) {
+		logSentMsg(data, len);
+		return 0;
+	} else {
+		flib_log_w("Failed or incomplete IPC write: engine connection lost.");
+		flib_socket_close(ipc->sock);
+		ipc->sock = NULL;
+		return -1;
+	}
+}
+
+int flib_ipcbase_send_message(flib_ipcbase *ipc, void *data, size_t len) {
+	if(log_badargs_if3(ipc==NULL, data==NULL && len>0, len>255)) {
+		return -1;
+	}
+
+	uint8_t sendbuf[256];
+	sendbuf[0] = len;
+	memcpy(sendbuf+1, data, len);
+	return flib_ipcbase_send_raw(ipc, sendbuf, len+1);
+}
+
+void flib_ipcbase_accept(flib_ipcbase *ipc) {
+	if(!log_badargs_if(ipc==NULL) && !ipc->sock && ipc->acceptor) {
+		ipc->sock = flib_socket_accept(ipc->acceptor, true);
+		if(ipc->sock) {
+			flib_log_d("IPC connection accepted.");
+			flib_acceptor_close(ipc->acceptor);
+			ipc->acceptor = NULL;
+		}
+	}
+}
diff --git a/project_files/frontlib/ipc/ipcbase.h b/project_files/frontlib/ipc/ipcbase.h
new file mode 100644
index 0000000..8daaa1d
--- /dev/null
+++ b/project_files/frontlib/ipc/ipcbase.h
@@ -0,0 +1,105 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/*
+ * Low-level protocol support for the IPC connection to the engine.
+ */
+#ifndef IPCBASE_H_
+#define IPCBASE_H_
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#define IPCBASE_MAPMSG_BYTES 4097
+
+typedef enum {IPC_NOT_CONNECTED, IPC_LISTENING, IPC_CONNECTED} IpcState;
+
+typedef struct _flib_ipcbase flib_ipcbase;
+
+/**
+ * Start an engine connection by listening on a random port. The selected port can
+ * be queried with flib_ipcbase_port and has to be passed to the engine.
+ *
+ * Returns NULL on error. Destroy the created object with flib_ipcbase_destroy.
+ *
+ * We stop accepting new connections once a connection has been established, so you
+ * need to create a new ipcbase in order to start a new connection.
+ */
+flib_ipcbase *flib_ipcbase_create();
+
+/**
+ * Return the listening port
+ */
+uint16_t flib_ipcbase_port(flib_ipcbase *ipc);
+
+/**
+ * Free resources and close sockets. NULL safe.
+ */
+void flib_ipcbase_destroy(flib_ipcbase *ipc);
+
+/**
+ * Determine the current connection state
+ */
+IpcState flib_ipcbase_state(flib_ipcbase *ipc);
+
+/**
+ * Receive a single message (up to 256 bytes) and copy it into the data buffer.
+ * Returns the length of the received message, a negative value if no message could
+ * be read.
+ *
+ * The first byte of a message is its content length, which is one less than the returned
+ * value.
+ *
+ * Note: When a connection is closed, you probably want to call this function until
+ * no further message is returned, to ensure you see all messages that were sent
+ * before the connection closed.
+ */
+int flib_ipcbase_recv_message(flib_ipcbase *ipc, void *data);
+
+/**
+ * Try to receive 4097 bytes. This is the size of the reply the engine sends
+ * when successfully queried for map data. The first 4096 bytes are a bit-packed
+ * twocolor image of the map (256x128), the last byte is the number of hogs that
+ * fit on the map.
+ */
+int flib_ipcbase_recv_map(flib_ipcbase *ipc, void *data);
+
+/**
+ * Blocking send bytes over the socket. No message framing will be added.
+ * Returns 0 on success.
+ */
+int flib_ipcbase_send_raw(flib_ipcbase *ipc, const void *data, size_t len);
+
+/**
+ * Write a single message (up to 255 bytes) to the engine. This call blocks until the
+ * message is completely written or the connection is closed or an error occurs.
+ *
+ * Calling this function in a state other than IPC_CONNECTED will fail immediately.
+ * Returns 0 on success.
+ */
+int flib_ipcbase_send_message(flib_ipcbase *ipc, void *data, size_t len);
+
+/**
+ * Try to accept a connection. Only has an effect in state IPC_LISTENING.
+ */
+void flib_ipcbase_accept(flib_ipcbase *ipc);
+
+#endif /* IPCBASE_H_ */
+
diff --git a/project_files/frontlib/ipc/ipcprotocol.c b/project_files/frontlib/ipc/ipcprotocol.c
new file mode 100644
index 0000000..f61556b
--- /dev/null
+++ b/project_files/frontlib/ipc/ipcprotocol.c
@@ -0,0 +1,316 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "ipcprotocol.h"
+#include "../util/util.h"
+#include "../util/logging.h"
+#include "../md5/md5.h"
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <inttypes.h>
+#include <stdlib.h>
+
+int flib_ipc_append_message(flib_vector *vec, const char *fmt, ...) {
+	int result = -1;
+	if(!log_badargs_if2(vec==NULL, fmt==NULL)) {
+		// 1 byte size prefix, 255 bytes max message length, 1 0-byte for vsnprintf
+		char msgbuffer[257];
+
+		// Format the message, leaving one byte at the start for the length
+		va_list argp;
+		va_start(argp, fmt);
+		int msgSize = vsnprintf(msgbuffer+1, 256, fmt, argp);
+		va_end(argp);
+
+		if(!log_e_if(msgSize > 255, "Message too long (%u bytes)", (unsigned)msgSize)
+				&& !log_e_if(msgSize < 0, "printf error")) {
+			// Add the length prefix
+			((uint8_t*)msgbuffer)[0] = msgSize;
+
+			// Append it to the vector
+			result = flib_vector_append(vec, msgbuffer, msgSize+1);
+		}
+	}
+	return result;
+}
+
+int flib_ipc_append_mapconf(flib_vector *vec, const flib_map *map, bool mappreview) {
+	int result = -1;
+	flib_vector *tempvector = flib_vector_create();
+	if(!log_badargs_if2(vec==NULL, map==NULL)) {
+		bool error = false;
+
+		if(map->mapgen == MAPGEN_NAMED) {
+			error |= log_e_if(!map->name, "Missing map name")
+					|| flib_ipc_append_message(tempvector, "emap %s", map->name);
+		}
+		if(!mappreview) {
+			error |= log_e_if(!map->theme, "Missing map theme")
+					|| flib_ipc_append_message(tempvector, "etheme %s", map->theme);
+		}
+		error |= flib_ipc_append_seed(tempvector, map->seed);
+		error |= flib_ipc_append_message(tempvector, "e$template_filter %i", map->templateFilter);
+		error |= flib_ipc_append_message(tempvector, "e$mapgen %i", map->mapgen);
+
+		if(map->mapgen == MAPGEN_MAZE) {
+			error |= flib_ipc_append_message(tempvector, "e$maze_size %i", map->mazeSize);
+		}
+		if(map->mapgen == MAPGEN_DRAWN) {
+			/*
+			 * We have to split the drawn map data into several edraw messages here because
+			 * it can be longer than the maximum message size.
+			 */
+			const char *edraw = "edraw ";
+			int edrawlen = strlen(edraw);
+			for(size_t offset=0; offset<map->drawDataSize; offset+=200) {
+				size_t bytesRemaining = map->drawDataSize-offset;
+				int fragmentsize = bytesRemaining < 200 ? bytesRemaining : 200;
+				uint8_t messagesize = edrawlen + fragmentsize;
+				error |= flib_vector_append(tempvector, &messagesize, 1);
+				error |= flib_vector_append(tempvector, edraw, edrawlen);
+				error |= flib_vector_append(tempvector, map->drawData+offset, fragmentsize);
+			}
+		}
+
+		if(!log_e_if(error, "Error generating map config")) {
+			// Message created, now we can copy everything.
+			flib_constbuffer constbuf = flib_vector_as_constbuffer(tempvector);
+			if(!flib_vector_append(vec, constbuf.data, constbuf.size)) {
+				result = 0;
+			}
+		}
+	}
+	flib_vector_destroy(tempvector);
+	return result;
+}
+
+int flib_ipc_append_seed(flib_vector *vec, const char *seed) {
+	if(log_badargs_if2(vec==NULL, seed==NULL)) {
+		return -1;
+	}
+	return flib_ipc_append_message(vec, "eseed %s", seed);
+}
+
+int flib_ipc_append_script(flib_vector *vec, const char *script) {
+	int result = -1;
+	if(!log_badargs_if2(vec==NULL, script==NULL)) {
+		result = flib_ipc_append_message(vec, "escript %s", script);
+	}
+	return result;
+}
+
+int flib_ipc_append_style(flib_vector *vec, const char *style) {
+	int result = -1;
+	char *copy = flib_strdupnull(style);
+	if(!log_badargs_if(vec==NULL) && copy) {
+		if(!strcmp("Normal", copy)) {
+			// "Normal" means no gametype script
+			// TODO if an empty script called "Normal" is added to the scripts directory this can be removed
+			result = 0;
+		} else {
+			size_t len = strlen(copy);
+			for(size_t i=0; i<len; i++) {
+				if(copy[i] == ' ') {
+					copy[i] = '_';
+				}
+			}
+
+			result = flib_ipc_append_message(vec, "escript %s%s.lua", MULTIPLAYER_SCRIPT_PATH, copy);
+		}
+	}
+	free(copy);
+	return result;
+}
+
+static uint32_t buildModFlags(const flib_scheme *scheme) {
+	uint32_t result = 0;
+	for(int i=0; i<flib_meta.modCount; i++) {
+		if(scheme->mods[i]) {
+			int bitmaskIndex = flib_meta.mods[i].bitmaskIndex;
+			result |= (UINT32_C(1) << bitmaskIndex);
+		}
+	}
+	return result;
+}
+
+int flib_ipc_append_gamescheme(flib_vector *vec, const flib_scheme *scheme) {
+	int result = -1;
+	flib_vector *tempvector = flib_vector_create();
+	if(!log_badargs_if2(vec==NULL, scheme==NULL) && tempvector) {
+		bool error = false;
+		error |= flib_ipc_append_message(tempvector, "e$gmflags %"PRIu32, buildModFlags(scheme));
+		for(int i=0; i<flib_meta.settingCount; i++) {
+			if(flib_meta.settings[i].engineCommand) {
+				int value = scheme->settings[i];
+				if(flib_meta.settings[i].maxMeansInfinity) {
+					value = value>=flib_meta.settings[i].max ? 9999 : value;
+				}
+				if(flib_meta.settings[i].times1000) {
+					value *= 1000;
+				}
+				error |= flib_ipc_append_message(tempvector, "%s %i", flib_meta.settings[i].engineCommand, value);
+			}
+		}
+
+		if(!error) {
+			// Message created, now we can copy everything.
+			flib_constbuffer constbuf = flib_vector_as_constbuffer(tempvector);
+			if(!flib_vector_append(vec, constbuf.data, constbuf.size)) {
+				result = 0;
+			}
+		}
+	}
+	flib_vector_destroy(tempvector);
+	return result;
+}
+
+static int appendWeaponSet(flib_vector *vec, flib_weaponset *set) {
+	return flib_ipc_append_message(vec, "eammloadt %s", set->loadout)
+		|| flib_ipc_append_message(vec, "eammprob %s", set->crateprob)
+		|| flib_ipc_append_message(vec, "eammdelay %s", set->delay)
+		|| flib_ipc_append_message(vec, "eammreinf %s", set->crateammo);
+}
+
+static void calculateMd5Hex(const char *in, char out[33]) {
+	md5_state_t md5state;
+	uint8_t md5bytes[16];
+	md5_init(&md5state);
+	md5_append(&md5state, (unsigned char*)in, strlen(in));
+	md5_finish(&md5state, md5bytes);
+	for(int i=0;i<sizeof(md5bytes); i++) {
+		snprintf(out+i*2, 3, "%02x", (unsigned)md5bytes[i]);
+	}
+}
+
+static int flib_ipc_append_addteam(flib_vector *vec, const flib_team *team, bool perHogAmmo, bool noAmmoStore) {
+	int result = -1;
+	flib_vector *tempvector = flib_vector_create();
+	if(!log_badargs_if2(vec==NULL, team==NULL) && tempvector) {
+		bool error = false;
+
+		if(!perHogAmmo && !noAmmoStore) {
+			error = error
+					|| appendWeaponSet(tempvector, team->hogs[0].weaponset)
+					|| flib_ipc_append_message(tempvector, "eammstore");
+		}
+
+		char md5Hex[33];
+		calculateMd5Hex(team->ownerName ? team->ownerName : "", md5Hex);
+		if(team->colorIndex<0 || team->colorIndex>=flib_teamcolor_count) {
+			flib_log_e("Color index out of bounds for team %s: %i", team->name, team->colorIndex);
+			error = true;
+		} else {
+			error |= flib_ipc_append_message(tempvector, "eaddteam %s %"PRIu32" %s", md5Hex, flib_teamcolors[team->colorIndex], team->name);
+		}
+
+		if(team->remoteDriven) {
+			error |= flib_ipc_append_message(tempvector, "erdriven");
+		}
+
+		error |= flib_ipc_append_message(tempvector, "egrave %s", team->grave);
+		error |= flib_ipc_append_message(tempvector, "efort %s", team->fort);
+		error |= flib_ipc_append_message(tempvector, "evoicepack %s", team->voicepack);
+		error |= flib_ipc_append_message(tempvector, "eflag %s", team->flag);
+
+		for(int i=0; i<team->bindingCount; i++) {
+			error |= flib_ipc_append_message(tempvector, "ebind %s %s", team->bindings[i].binding, team->bindings[i].action);
+		}
+
+		for(int i=0; i<team->hogsInGame; i++) {
+			if(perHogAmmo && !noAmmoStore) {
+				error |= appendWeaponSet(tempvector, team->hogs[i].weaponset);
+			}
+			error |= flib_ipc_append_message(tempvector, "eaddhh %i %i %s", team->hogs[i].difficulty, team->hogs[i].initialHealth, team->hogs[i].name);
+			error |= flib_ipc_append_message(tempvector, "ehat %s", team->hogs[i].hat);
+		}
+
+		if(!error) {
+			// Message created, now we can copy everything.
+			flib_constbuffer constbuf = flib_vector_as_constbuffer(tempvector);
+			if(!flib_vector_append(vec, constbuf.data, constbuf.size)) {
+				result = 0;
+			}
+		}
+	}
+	flib_vector_destroy(tempvector);
+	return result;
+}
+
+int flib_ipc_append_fullconfig(flib_vector *vec, const flib_gamesetup *setup, bool netgame) {
+	int result = -1;
+	flib_vector *tempvector = flib_vector_create();
+	if(!log_badargs_if2(vec==NULL, setup==NULL) && tempvector) {
+		bool error = false;
+		bool perHogAmmo = false;
+		bool sharedAmmo = false;
+
+		error |= flib_ipc_append_message(vec, netgame ? "TN" : "TL");
+		if(setup->map) {
+			error |= flib_ipc_append_mapconf(tempvector, setup->map, false);
+		}
+		if(setup->style) {
+			error |= flib_ipc_append_style(tempvector, setup->style);
+		}
+		if(setup->gamescheme) {
+			error |= flib_ipc_append_gamescheme(tempvector, setup->gamescheme);
+			sharedAmmo = flib_scheme_get_mod(setup->gamescheme, "sharedammo");
+			// Shared ammo has priority over per-hog ammo
+			perHogAmmo = !sharedAmmo && flib_scheme_get_mod(setup->gamescheme, "perhogammo");
+		}
+		if(setup->teamlist->teams && setup->teamlist->teamCount>0) {
+			int *clanColors = flib_calloc(setup->teamlist->teamCount, sizeof(int));
+			if(!clanColors) {
+				error = true;
+			} else {
+				int clanCount = 0;
+				for(int i=0; !error && i<setup->teamlist->teamCount; i++) {
+					flib_team *team = setup->teamlist->teams[i];
+					// Find the clan index of this team (clans are identified by color).
+					bool newClan = false;
+					int clan = 0;
+					while(clan<clanCount && clanColors[clan] != team->colorIndex) {
+						clan++;
+					}
+					if(clan==clanCount) {
+						newClan = true;
+						clanCount++;
+						clanColors[clan] = team->colorIndex;
+					}
+
+					// If shared ammo is active, only add an ammo store for the first team in each clan.
+					bool noAmmoStore = sharedAmmo&&!newClan;
+					error |= flib_ipc_append_addteam(tempvector, setup->teamlist->teams[i], perHogAmmo, noAmmoStore);
+				}
+			}
+			free(clanColors);
+		}
+		error |= flib_ipc_append_message(tempvector, "!");
+
+		if(!error) {
+			// Message created, now we can copy everything.
+			flib_constbuffer constbuf = flib_vector_as_constbuffer(tempvector);
+			if(!flib_vector_append(vec, constbuf.data, constbuf.size)) {
+				result = 0;
+			}
+		}
+	}
+	return result;
+}
diff --git a/project_files/frontlib/ipc/ipcprotocol.h b/project_files/frontlib/ipc/ipcprotocol.h
new file mode 100644
index 0000000..8abbd70
--- /dev/null
+++ b/project_files/frontlib/ipc/ipcprotocol.h
@@ -0,0 +1,93 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef IPCPROTOCOL_H_
+#define IPCPROTOCOL_H_
+
+#include "../util/buffer.h"
+#include "../model/map.h"
+#include "../model/team.h"
+#include "../model/scheme.h"
+#include "../model/gamesetup.h"
+
+#include <stdbool.h>
+
+/**
+ * Create a message in the IPC protocol format and add it to
+ * the vector. Use a format string and extra parameters as with printf.
+ *
+ * Returns nonzero if something goes wrong. In that case the buffer
+ * contents are unaffected.
+ */
+int flib_ipc_append_message(flib_vector *vec, const char *fmt, ...);
+
+/**
+ * Append IPC messages to the buffer that configure the engine for
+ * this map.
+ *
+ * Unfortunately the engine needs a slightly different configuration
+ * for generating a map preview.
+ *
+ * Returns nonzero if something goes wrong. In that case the buffer
+ * contents are unaffected.
+ */
+int flib_ipc_append_mapconf(flib_vector *vec, const flib_map *map, bool mappreview);
+
+/**
+ * Append a seed message to the buffer.
+ *
+ * Returns nonzero if something goes wrong. In that case the buffer
+ * contents are unaffected.
+ */
+int flib_ipc_append_seed(flib_vector *vec, const char *seed);
+
+/**
+ * Append a script to the buffer (e.g. "Missions/Training/Basic_Training_-_Bazooka.lua")
+ *
+ * Returns nonzero if something goes wrong. In that case the buffer
+ * contents are unaffected.
+ */
+int flib_ipc_append_script(flib_vector *vec, const char *script);
+
+/**
+ * Append a game style to the buffer. (e.g. "Capture the Flag")
+ *
+ * Returns nonzero if something goes wrong. In that case the buffer
+ * contents are unaffected.
+ */
+int flib_ipc_append_style(flib_vector *vec, const char *style);
+
+/**
+ * Append the game scheme to the buffer.
+ *
+ * Returns nonzero if something goes wrong. In that case the buffer
+ * contents are unaffected.
+ */
+int flib_ipc_append_gamescheme(flib_vector *vec, const flib_scheme *scheme);
+
+/**
+ * Append the entire game config to the buffer (including the final "!" that marks the
+ * end of configuration data for the engine)
+ *
+ * Returns nonzero if something goes wrong. In that case the buffer
+ * contents are unaffected.
+ */
+int flib_ipc_append_fullconfig(flib_vector *vec, const flib_gamesetup *setup, bool netgame);
+
+#endif /* IPCPROTOCOL_H_ */
diff --git a/project_files/frontlib/ipc/mapconn.c b/project_files/frontlib/ipc/mapconn.c
new file mode 100644
index 0000000..2be7058
--- /dev/null
+++ b/project_files/frontlib/ipc/mapconn.c
@@ -0,0 +1,196 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "mapconn.h"
+#include "ipcbase.h"
+#include "ipcprotocol.h"
+
+#include "../util/logging.h"
+#include "../util/buffer.h"
+#include "../util/util.h"
+
+#include <stdlib.h>
+
+typedef enum {
+	AWAIT_CONNECTION,
+	AWAIT_REPLY,
+	AWAIT_CLOSE,
+	FINISHED
+} mapconn_state;
+
+struct _flib_mapconn {
+	uint8_t mapBuffer[IPCBASE_MAPMSG_BYTES];
+	flib_ipcbase *ipcBase;
+	flib_vector *configBuffer;
+
+	mapconn_state progress;
+
+	void (*onSuccessCb)(void*, const uint8_t*, int);
+	void *onSuccessCtx;
+
+	void (*onFailureCb)(void*, const char*);
+	void *onFailureCtx;
+
+	bool running;
+	bool destroyRequested;
+};
+
+static void noop_handleSuccess(void *context, const uint8_t *bitmap, int numHedgehogs) {}
+static void noop_handleFailure(void *context, const char *errormessage) {}
+
+static void clearCallbacks(flib_mapconn *conn) {
+	conn->onSuccessCb = &noop_handleSuccess;
+	conn->onFailureCb = &noop_handleFailure;
+}
+
+static flib_vector *createConfigBuffer(const flib_map *mapdesc) {
+	flib_vector *result = NULL;
+	flib_vector *tempbuffer = flib_vector_create();
+	if(tempbuffer) {
+		bool error = false;
+		error |= flib_ipc_append_mapconf(tempbuffer, mapdesc, true);
+		error |= flib_ipc_append_message(tempbuffer, "!");
+		if(!error) {
+			result = tempbuffer;
+			tempbuffer = NULL;
+		}
+	}
+	flib_vector_destroy(tempbuffer);
+	return result;
+}
+
+flib_mapconn *flib_mapconn_create(const flib_map *mapdesc) {
+	if(log_badargs_if(mapdesc==NULL)) {
+		return NULL;
+	}
+	flib_mapconn *result = NULL;
+	flib_mapconn *tempConn = flib_calloc(1, sizeof(flib_mapconn));
+	if(tempConn) {
+		tempConn->ipcBase = flib_ipcbase_create();
+		tempConn->configBuffer = createConfigBuffer(mapdesc);
+		if(tempConn->ipcBase && tempConn->configBuffer) {
+			tempConn->progress = AWAIT_CONNECTION;
+			clearCallbacks(tempConn);
+			result = tempConn;
+			tempConn = NULL;
+		}
+	}
+	flib_mapconn_destroy(tempConn);
+	return result;
+}
+
+void flib_mapconn_destroy(flib_mapconn *conn) {
+	if(conn) {
+		if(conn->running) {
+			/*
+			 * The function was called from a callback, so the tick function is still running
+			 * and we delay the actual destruction. We ensure no further callbacks will be
+			 * sent to prevent surprises.
+			 */
+			clearCallbacks(conn);
+			conn->destroyRequested = true;
+		} else {
+			flib_ipcbase_destroy(conn->ipcBase);
+			flib_vector_destroy(conn->configBuffer);
+			free(conn);
+		}
+	}
+}
+
+int flib_mapconn_getport(flib_mapconn *conn) {
+	if(log_badargs_if(conn==NULL)) {
+		return 0;
+	}
+	return flib_ipcbase_port(conn->ipcBase);
+}
+
+void flib_mapconn_onSuccess(flib_mapconn *conn, void (*callback)(void* context, const uint8_t *bitmap, int numHedgehogs), void *context) {
+	if(!log_badargs_if(conn==NULL)) {
+		conn->onSuccessCb = callback ? callback : &noop_handleSuccess;
+		conn->onSuccessCtx = context;
+	}
+}
+
+void flib_mapconn_onFailure(flib_mapconn *conn, void (*callback)(void* context, const char *errormessage), void *context) {
+	if(!log_badargs_if(conn==NULL)) {
+		conn->onFailureCb = callback ? callback : &noop_handleFailure;
+		conn->onFailureCtx = context;
+	}
+}
+
+static void flib_mapconn_wrappedtick(flib_mapconn *conn) {
+	if(conn->progress == AWAIT_CONNECTION) {
+		flib_ipcbase_accept(conn->ipcBase);
+		switch(flib_ipcbase_state(conn->ipcBase)) {
+		case IPC_CONNECTED:
+			{
+				flib_constbuffer configBuffer = flib_vector_as_constbuffer(conn->configBuffer);
+				if(flib_ipcbase_send_raw(conn->ipcBase, configBuffer.data, configBuffer.size)) {
+					conn->progress = FINISHED;
+					conn->onFailureCb(conn->onFailureCtx, "Error sending map information to the engine.");
+					return;
+				} else {
+					conn->progress = AWAIT_REPLY;
+				}
+			}
+			break;
+		case IPC_NOT_CONNECTED:
+			conn->progress = FINISHED;
+			conn->onFailureCb(conn->onFailureCtx, "Engine connection closed unexpectedly.");
+			return;
+		default:
+			break;
+		}
+	}
+
+	if(conn->progress == AWAIT_REPLY) {
+		if(flib_ipcbase_recv_map(conn->ipcBase, conn->mapBuffer) >= 0) {
+			conn->progress = AWAIT_CLOSE;
+		} else if(flib_ipcbase_state(conn->ipcBase) != IPC_CONNECTED) {
+			conn->progress = FINISHED;
+			conn->onFailureCb(conn->onSuccessCtx, "Engine connection closed unexpectedly.");
+			return;
+		}
+	}
+
+	if(conn->progress == AWAIT_CLOSE) {
+		// Just do throwaway reads so we find out when the engine disconnects
+		uint8_t buf[256];
+		flib_ipcbase_recv_message(conn->ipcBase, buf);
+		if(flib_ipcbase_state(conn->ipcBase) != IPC_CONNECTED) {
+			conn->progress = FINISHED;
+			conn->onSuccessCb(conn->onSuccessCtx, conn->mapBuffer, conn->mapBuffer[IPCBASE_MAPMSG_BYTES-1]);
+			return;
+		}
+	}
+}
+
+void flib_mapconn_tick(flib_mapconn *conn) {
+	if(!log_badargs_if(conn==NULL)
+			&& !log_w_if(conn->running, "Call to flib_mapconn_tick from a callback")
+			&& !log_w_if(conn->progress == FINISHED, "We are already done.")) {
+		conn->running = true;
+		flib_mapconn_wrappedtick(conn);
+		conn->running = false;
+
+		if(conn->destroyRequested) {
+			flib_mapconn_destroy(conn);
+		}
+	}
+}
diff --git a/project_files/frontlib/ipc/mapconn.h b/project_files/frontlib/ipc/mapconn.h
new file mode 100644
index 0000000..efb0bb0
--- /dev/null
+++ b/project_files/frontlib/ipc/mapconn.h
@@ -0,0 +1,116 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/**
+ * Functions for querying a map preview from the engine, which includes both a two-color image
+ * and the number of hogs this map is suitable for.
+ *
+ * The general usage is to first create a mapconn object by calling flib_mapconn_create.
+ * That will cause the frontlib to listen on a random port which can be queried using
+ * flib_mapconn_getport(). You should also register your callback functions right at the start
+ * to ensure you don't miss any callbacks.
+ *
+ * Next, start the engine (that part is up to you) with the appropriate command line arguments
+ * for a map preview request.
+ *
+ * In order to allow the mapconn to run, you should regularly call flib_mapconn_tick(), which
+ * performs network I/O and calls your callbacks if the map has been generated or an error
+ * has occurred. Once either the onSuccess or onFailure callback is called, you should destroy
+ * the mapconn and stop calling tick().
+ */
+
+#ifndef IPC_MAPCONN_H_
+#define IPC_MAPCONN_H_
+
+#include "../model/map.h"
+
+#include <stdint.h>
+
+#define MAPIMAGE_WIDTH 256
+#define MAPIMAGE_HEIGHT 128
+#define MAPIMAGE_BYTES (MAPIMAGE_WIDTH/8*MAPIMAGE_HEIGHT)
+
+typedef struct _flib_mapconn flib_mapconn;
+
+/**
+ * Start a new map rendering connection (mapconn). This means a listening socket
+ * will be started on a random unused port, waiting for a connection from the
+ * engine process. Once this connection is established, the required information
+ * will be sent to the engine, and the reply is read.
+ *
+ * The map must be a regular, maze or drawn map - for a preview of a named map,
+ * use the preview images in the map's directory, and for the hog count read the
+ * map information (e.g. using flib_mapcfg_read).
+ *
+ * No NULL parameters allowed, returns NULL on failure.
+ * Use flib_mapconn_destroy to free the returned object.
+ */
+flib_mapconn *flib_mapconn_create(const flib_map *mapdesc);
+
+/**
+ * Destroy the mapconn object. Passing NULL is allowed and does nothing.
+ * flib_mapconn_destroy may be called from inside a callback function.
+ */
+void flib_mapconn_destroy(flib_mapconn *conn);
+
+/**
+ * Returns the port on which the mapconn is listening. Only fails if you
+ * pass NULL (not allowed), in that case 0 is returned.
+ */
+int flib_mapconn_getport(flib_mapconn *conn);
+
+/**
+ * Set a callback which will receive the rendered map if the rendering succeeds.
+ *
+ * Expected callback signature:
+ * void handleSuccess(void *context, const uint8_t *bitmap, int numHedgehogs)
+ *
+ * The context passed to the callback is the same pointer you provided when
+ * registering the callback. bitmap is a pointer to a buffer of size MAPIMAGE_BYTES
+ * containing a bit-packed image of size MAPIMAGE_WIDTH * MAPIMAGE_HEIGHT.
+ * numHedgehogs is the number of hogs that fit on this map.
+ *
+ * The bitmap pointer passed to the callback belongs to the caller,
+ * so it should not be stored elsewhere. Note that it remains valid
+ * inside the callback method even if flib_mapconn_destroy is called.
+ */
+void flib_mapconn_onSuccess(flib_mapconn *conn, void (*callback)(void* context, const uint8_t *bitmap, int numHedgehogs), void *context);
+
+/**
+ * Set a callback which will receive an error message if rendering fails.
+ *
+ * Expected callback signature:
+ * void handleFailure(void *context, const char *errormessage)
+ *
+ * The context passed to the callback is the same pointer you provided when
+ * registering the callback.
+ *
+ * The error message passed to the callback belongs to the caller,
+ * so it should not be stored elsewhere. Note that it remains valid
+ * inside the callback method even if flib_mapconn_destroy is called.
+ */
+void flib_mapconn_onFailure(flib_mapconn *conn, void (*callback)(void* context, const char *errormessage), void *context);
+
+/**
+ * Perform I/O operations and call callbacks if something interesting happens.
+ * Should be called regularly.
+ */
+void flib_mapconn_tick(flib_mapconn *conn);
+
+#endif
diff --git a/project_files/frontlib/md5/md5.c b/project_files/frontlib/md5/md5.c
new file mode 100644
index 0000000..c35d96c
--- /dev/null
+++ b/project_files/frontlib/md5/md5.c
@@ -0,0 +1,381 @@
+/*
+  Copyright (C) 1999, 2000, 2002 Aladdin Enterprises.  All rights reserved.
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  L. Peter Deutsch
+  ghost at aladdin.com
+
+ */
+/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
+/*
+  Independent implementation of MD5 (RFC 1321).
+
+  This code implements the MD5 Algorithm defined in RFC 1321, whose
+  text is available at
+	http://www.ietf.org/rfc/rfc1321.txt
+  The code is derived from the text of the RFC, including the test suite
+  (section A.5) but excluding the rest of Appendix A.  It does not include
+  any code or documentation that is identified in the RFC as being
+  copyrighted.
+
+  The original and principal author of md5.c is L. Peter Deutsch
+  <ghost at aladdin.com>.  Other authors are noted in the change history
+  that follows (in reverse chronological order):
+
+  2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
+	either statically or dynamically; added missing #include <string.h>
+	in library.
+  2002-03-11 lpd Corrected argument list for main(), and added int return
+	type, in test program and T value program.
+  2002-02-21 lpd Added missing #include <stdio.h> in test program.
+  2000-07-03 lpd Patched to eliminate warnings about "constant is
+	unsigned in ANSI C, signed in traditional"; made test program
+	self-checking.
+  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
+  1999-05-03 lpd Original version.
+ */
+
+#include "md5.h"
+#include <string.h>
+
+#undef BYTE_ORDER	/* 1 = big-endian, -1 = little-endian, 0 = unknown */
+#ifdef ARCH_IS_BIG_ENDIAN
+#  define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
+#else
+#  define BYTE_ORDER 0
+#endif
+
+#define T_MASK ((md5_word_t)~0)
+#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
+#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
+#define T3    0x242070db
+#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
+#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
+#define T6    0x4787c62a
+#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
+#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
+#define T9    0x698098d8
+#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
+#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
+#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
+#define T13    0x6b901122
+#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
+#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
+#define T16    0x49b40821
+#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
+#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
+#define T19    0x265e5a51
+#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
+#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
+#define T22    0x02441453
+#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
+#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
+#define T25    0x21e1cde6
+#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
+#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
+#define T28    0x455a14ed
+#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
+#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
+#define T31    0x676f02d9
+#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
+#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
+#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
+#define T35    0x6d9d6122
+#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
+#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
+#define T38    0x4bdecfa9
+#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
+#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
+#define T41    0x289b7ec6
+#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
+#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
+#define T44    0x04881d05
+#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
+#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
+#define T47    0x1fa27cf8
+#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
+#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
+#define T50    0x432aff97
+#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
+#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
+#define T53    0x655b59c3
+#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
+#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
+#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
+#define T57    0x6fa87e4f
+#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
+#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
+#define T60    0x4e0811a1
+#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
+#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
+#define T63    0x2ad7d2bb
+#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
+
+
+static void
+md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
+{
+    md5_word_t
+	a = pms->abcd[0], b = pms->abcd[1],
+	c = pms->abcd[2], d = pms->abcd[3];
+    md5_word_t t;
+#if BYTE_ORDER > 0
+    /* Define storage only for big-endian CPUs. */
+    md5_word_t X[16];
+#else
+    /* Define storage for little-endian or both types of CPUs. */
+    md5_word_t xbuf[16];
+    const md5_word_t *X;
+#endif
+
+    {
+#if BYTE_ORDER == 0
+	/*
+	 * Determine dynamically whether this is a big-endian or
+	 * little-endian machine, since we can use a more efficient
+	 * algorithm on the latter.
+	 */
+	static const int w = 1;
+
+	if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
+#endif
+#if BYTE_ORDER <= 0		/* little-endian */
+	{
+	    /*
+	     * On little-endian machines, we can process properly aligned
+	     * data without copying it.
+	     */
+	    if (!((data - (const md5_byte_t *)0) & 3)) {
+		/* data are properly aligned */
+		X = (const md5_word_t *)data;
+	    } else {
+		/* not aligned */
+		memcpy(xbuf, data, 64);
+		X = xbuf;
+	    }
+	}
+#endif
+#if BYTE_ORDER == 0
+	else			/* dynamic big-endian */
+#endif
+#if BYTE_ORDER >= 0		/* big-endian */
+	{
+	    /*
+	     * On big-endian machines, we must arrange the bytes in the
+	     * right order.
+	     */
+	    const md5_byte_t *xp = data;
+	    int i;
+
+#  if BYTE_ORDER == 0
+	    X = xbuf;		/* (dynamic only) */
+#  else
+#    define xbuf X		/* (static only) */
+#  endif
+	    for (i = 0; i < 16; ++i, xp += 4)
+		xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
+	}
+#endif
+    }
+
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+
+    /* Round 1. */
+    /* Let [abcd k s i] denote the operation
+       a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
+#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
+#define SET(a, b, c, d, k, s, Ti)\
+  t = a + F(b,c,d) + X[k] + Ti;\
+  a = ROTATE_LEFT(t, s) + b
+    /* Do the following 16 operations. */
+    SET(a, b, c, d,  0,  7,  T1);
+    SET(d, a, b, c,  1, 12,  T2);
+    SET(c, d, a, b,  2, 17,  T3);
+    SET(b, c, d, a,  3, 22,  T4);
+    SET(a, b, c, d,  4,  7,  T5);
+    SET(d, a, b, c,  5, 12,  T6);
+    SET(c, d, a, b,  6, 17,  T7);
+    SET(b, c, d, a,  7, 22,  T8);
+    SET(a, b, c, d,  8,  7,  T9);
+    SET(d, a, b, c,  9, 12, T10);
+    SET(c, d, a, b, 10, 17, T11);
+    SET(b, c, d, a, 11, 22, T12);
+    SET(a, b, c, d, 12,  7, T13);
+    SET(d, a, b, c, 13, 12, T14);
+    SET(c, d, a, b, 14, 17, T15);
+    SET(b, c, d, a, 15, 22, T16);
+#undef SET
+
+     /* Round 2. */
+     /* Let [abcd k s i] denote the operation
+          a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
+#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+  t = a + G(b,c,d) + X[k] + Ti;\
+  a = ROTATE_LEFT(t, s) + b
+     /* Do the following 16 operations. */
+    SET(a, b, c, d,  1,  5, T17);
+    SET(d, a, b, c,  6,  9, T18);
+    SET(c, d, a, b, 11, 14, T19);
+    SET(b, c, d, a,  0, 20, T20);
+    SET(a, b, c, d,  5,  5, T21);
+    SET(d, a, b, c, 10,  9, T22);
+    SET(c, d, a, b, 15, 14, T23);
+    SET(b, c, d, a,  4, 20, T24);
+    SET(a, b, c, d,  9,  5, T25);
+    SET(d, a, b, c, 14,  9, T26);
+    SET(c, d, a, b,  3, 14, T27);
+    SET(b, c, d, a,  8, 20, T28);
+    SET(a, b, c, d, 13,  5, T29);
+    SET(d, a, b, c,  2,  9, T30);
+    SET(c, d, a, b,  7, 14, T31);
+    SET(b, c, d, a, 12, 20, T32);
+#undef SET
+
+     /* Round 3. */
+     /* Let [abcd k s t] denote the operation
+          a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define SET(a, b, c, d, k, s, Ti)\
+  t = a + H(b,c,d) + X[k] + Ti;\
+  a = ROTATE_LEFT(t, s) + b
+     /* Do the following 16 operations. */
+    SET(a, b, c, d,  5,  4, T33);
+    SET(d, a, b, c,  8, 11, T34);
+    SET(c, d, a, b, 11, 16, T35);
+    SET(b, c, d, a, 14, 23, T36);
+    SET(a, b, c, d,  1,  4, T37);
+    SET(d, a, b, c,  4, 11, T38);
+    SET(c, d, a, b,  7, 16, T39);
+    SET(b, c, d, a, 10, 23, T40);
+    SET(a, b, c, d, 13,  4, T41);
+    SET(d, a, b, c,  0, 11, T42);
+    SET(c, d, a, b,  3, 16, T43);
+    SET(b, c, d, a,  6, 23, T44);
+    SET(a, b, c, d,  9,  4, T45);
+    SET(d, a, b, c, 12, 11, T46);
+    SET(c, d, a, b, 15, 16, T47);
+    SET(b, c, d, a,  2, 23, T48);
+#undef SET
+
+     /* Round 4. */
+     /* Let [abcd k s t] denote the operation
+          a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+  t = a + I(b,c,d) + X[k] + Ti;\
+  a = ROTATE_LEFT(t, s) + b
+     /* Do the following 16 operations. */
+    SET(a, b, c, d,  0,  6, T49);
+    SET(d, a, b, c,  7, 10, T50);
+    SET(c, d, a, b, 14, 15, T51);
+    SET(b, c, d, a,  5, 21, T52);
+    SET(a, b, c, d, 12,  6, T53);
+    SET(d, a, b, c,  3, 10, T54);
+    SET(c, d, a, b, 10, 15, T55);
+    SET(b, c, d, a,  1, 21, T56);
+    SET(a, b, c, d,  8,  6, T57);
+    SET(d, a, b, c, 15, 10, T58);
+    SET(c, d, a, b,  6, 15, T59);
+    SET(b, c, d, a, 13, 21, T60);
+    SET(a, b, c, d,  4,  6, T61);
+    SET(d, a, b, c, 11, 10, T62);
+    SET(c, d, a, b,  2, 15, T63);
+    SET(b, c, d, a,  9, 21, T64);
+#undef SET
+
+     /* Then perform the following additions. (That is increment each
+        of the four registers by the value it had before this block
+        was started.) */
+    pms->abcd[0] += a;
+    pms->abcd[1] += b;
+    pms->abcd[2] += c;
+    pms->abcd[3] += d;
+}
+
+void
+md5_init(md5_state_t *pms)
+{
+    pms->count[0] = pms->count[1] = 0;
+    pms->abcd[0] = 0x67452301;
+    pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
+    pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
+    pms->abcd[3] = 0x10325476;
+}
+
+void
+md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
+{
+    const md5_byte_t *p = data;
+    int left = nbytes;
+    int offset = (pms->count[0] >> 3) & 63;
+    md5_word_t nbits = (md5_word_t)(nbytes << 3);
+
+    if (nbytes <= 0)
+	return;
+
+    /* Update the message length. */
+    pms->count[1] += nbytes >> 29;
+    pms->count[0] += nbits;
+    if (pms->count[0] < nbits)
+	pms->count[1]++;
+
+    /* Process an initial partial block. */
+    if (offset) {
+	int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
+
+	memcpy(pms->buf + offset, p, copy);
+	if (offset + copy < 64)
+	    return;
+	p += copy;
+	left -= copy;
+	md5_process(pms, pms->buf);
+    }
+
+    /* Process full blocks. */
+    for (; left >= 64; p += 64, left -= 64)
+	md5_process(pms, p);
+
+    /* Process a final partial block. */
+    if (left)
+	memcpy(pms->buf, p, left);
+}
+
+void
+md5_finish(md5_state_t *pms, md5_byte_t digest[16])
+{
+    static const md5_byte_t pad[64] = {
+	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+    };
+    md5_byte_t data[8];
+    int i;
+
+    /* Save the length before padding. */
+    for (i = 0; i < 8; ++i)
+	data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
+    /* Pad to 56 bytes mod 64. */
+    md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
+    /* Append the length. */
+    md5_append(pms, data, 8);
+    for (i = 0; i < 16; ++i)
+	digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
+}
diff --git a/project_files/frontlib/md5/md5.h b/project_files/frontlib/md5/md5.h
new file mode 100644
index 0000000..a711fdc
--- /dev/null
+++ b/project_files/frontlib/md5/md5.h
@@ -0,0 +1,91 @@
+/*
+  Copyright (C) 1999, 2002 Aladdin Enterprises.  All rights reserved.
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  L. Peter Deutsch
+  ghost at aladdin.com
+
+ */
+/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */
+/*
+  Independent implementation of MD5 (RFC 1321).
+
+  This code implements the MD5 Algorithm defined in RFC 1321, whose
+  text is available at
+	http://www.ietf.org/rfc/rfc1321.txt
+  The code is derived from the text of the RFC, including the test suite
+  (section A.5) but excluding the rest of Appendix A.  It does not include
+  any code or documentation that is identified in the RFC as being
+  copyrighted.
+
+  The original and principal author of md5.h is L. Peter Deutsch
+  <ghost at aladdin.com>.  Other authors are noted in the change history
+  that follows (in reverse chronological order):
+
+  2002-04-13 lpd Removed support for non-ANSI compilers; removed
+	references to Ghostscript; clarified derivation from RFC 1321;
+	now handles byte order either statically or dynamically.
+  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
+	added conditionalization for C++ compilation from Martin
+	Purschke <purschke at bnl.gov>.
+  1999-05-03 lpd Original version.
+ */
+
+#ifndef md5_INCLUDED
+#  define md5_INCLUDED
+
+/*
+ * This package supports both compile-time and run-time determination of CPU
+ * byte order.  If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
+ * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
+ * defined as non-zero, the code will be compiled to run only on big-endian
+ * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
+ * run on either big- or little-endian CPUs, but will run slightly less
+ * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
+ */
+
+typedef unsigned char md5_byte_t; /* 8-bit byte */
+typedef unsigned int md5_word_t; /* 32-bit word */
+
+/*! Define the state of the MD5 Algorithm. */
+typedef struct md5_state_s {
+    md5_word_t count[2];	/*! message length in bits, lsw first */
+    md5_word_t abcd[4];		/*! digest buffer */
+    md5_byte_t buf[64];		/*! accumulate block */
+} md5_state_t;
+
+#ifdef __cplusplus
+extern "C" 
+{
+#endif
+
+/*! Initialize the algorithm. */
+void md5_init(md5_state_t *pms);
+
+/*! Append a string to the message. */
+void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
+
+/*! Finish the message and return the digest. */
+void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
+
+#ifdef __cplusplus
+}  /* end extern "C" */
+#endif
+
+#endif /* md5_INCLUDED */
diff --git a/project_files/frontlib/model/gamesetup.c b/project_files/frontlib/model/gamesetup.c
new file mode 100644
index 0000000..54e34b9
--- /dev/null
+++ b/project_files/frontlib/model/gamesetup.c
@@ -0,0 +1,55 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "gamesetup.h"
+#include "../util/util.h"
+
+#include <stdlib.h>
+
+void flib_gamesetup_destroy(flib_gamesetup *gamesetup) {
+	if(gamesetup) {
+		free(gamesetup->style);
+		flib_scheme_destroy(gamesetup->gamescheme);
+		flib_map_destroy(gamesetup->map);
+		flib_teamlist_destroy(gamesetup->teamlist);
+		free(gamesetup);
+	}
+}
+
+flib_gamesetup *flib_gamesetup_copy(const flib_gamesetup *setup) {
+	if(!setup) {
+		return NULL;
+	}
+
+	flib_gamesetup *result = flib_calloc(1, sizeof(flib_gamesetup));
+	if(result) {
+		result->style = flib_strdupnull(setup->style);
+		result->gamescheme = flib_scheme_copy(setup->gamescheme);
+		result->map = flib_map_copy(setup->map);
+		result->teamlist = flib_teamlist_copy(setup->teamlist);
+		if((setup->style && !result->style)
+				|| (setup->gamescheme && !result->gamescheme)
+				|| (setup->map && !result->map)
+				|| (setup->teamlist && !result->teamlist)) {
+			flib_gamesetup_destroy(result);
+			result = NULL;
+		}
+	}
+	return result;
+}
diff --git a/project_files/frontlib/model/gamesetup.h b/project_files/frontlib/model/gamesetup.h
new file mode 100644
index 0000000..17d672d
--- /dev/null
+++ b/project_files/frontlib/model/gamesetup.h
@@ -0,0 +1,47 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/**
+ * A complete game configuration that contains all settings the engine needs to start a
+ * local or networked game.
+ */
+
+#ifndef MODEL_GAMESETUP_H_
+#define MODEL_GAMESETUP_H_
+
+#include "scheme.h"
+#include "weapon.h"
+#include "map.h"
+#include "teamlist.h"
+
+typedef struct {
+    char *style;				//!< e.g. "Capture the Flag"
+    flib_scheme *gamescheme;
+    flib_map *map;
+	flib_teamlist *teamlist;
+} flib_gamesetup;
+
+void flib_gamesetup_destroy(flib_gamesetup *gamesetup);
+
+/**
+ * Deep-copy of the flib_gamesetup.
+ */
+flib_gamesetup *flib_gamesetup_copy(const flib_gamesetup *gamesetup);
+
+#endif
diff --git a/project_files/frontlib/model/map.c b/project_files/frontlib/model/map.c
new file mode 100644
index 0000000..931899d
--- /dev/null
+++ b/project_files/frontlib/model/map.c
@@ -0,0 +1,110 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "map.h"
+
+#include "../util/inihelper.h"
+#include "../util/util.h"
+#include "../util/logging.h"
+
+#include <stdlib.h>
+
+flib_map *flib_map_create_regular(const char *seed, const char *theme, int templateFilter) {
+	if(log_badargs_if2(seed==NULL, theme==NULL)) {
+		return NULL;
+	}
+	flib_map newmap = {0};
+	newmap.mapgen = MAPGEN_REGULAR;
+	newmap.name = "+rnd+";
+	newmap.seed = (char*)seed;
+	newmap.theme = (char*)theme;
+	newmap.templateFilter = templateFilter;
+	return flib_map_copy(&newmap);
+}
+
+flib_map *flib_map_create_maze(const char *seed, const char *theme, int mazeSize) {
+	if(log_badargs_if2(seed==NULL, theme==NULL)) {
+		return NULL;
+	}
+	flib_map newmap = {0};
+	newmap.mapgen = MAPGEN_MAZE;
+	newmap.name = "+maze+";
+	newmap.seed = (char*)seed;
+	newmap.theme = (char*)theme;
+	newmap.mazeSize = mazeSize;
+	return flib_map_copy(&newmap);
+}
+
+flib_map *flib_map_create_named(const char *seed, const char *name) {
+	if(log_badargs_if2(seed==NULL, name==NULL)) {
+		return NULL;
+	}
+	flib_map newmap = {0};
+	newmap.mapgen = MAPGEN_NAMED;
+	newmap.name = (char*)name;
+	newmap.seed = (char*)seed;
+	return flib_map_copy(&newmap);
+}
+
+flib_map *flib_map_create_drawn(const char *seed, const char *theme, const uint8_t *drawData, size_t drawDataSize) {
+	if(log_badargs_if3(seed==NULL, theme==NULL, drawData==NULL)) {
+		return NULL;
+	}
+	flib_map newmap = {0};
+	newmap.mapgen = MAPGEN_DRAWN;
+	newmap.name = "+drawn+";
+	newmap.seed = (char*)seed;
+	newmap.theme = (char*)theme;
+	newmap.drawData = (uint8_t*) drawData;
+	newmap.drawDataSize = drawDataSize;
+	return flib_map_copy(&newmap);
+}
+
+flib_map *flib_map_copy(const flib_map *map) {
+	flib_map *result = NULL;
+	if(map) {
+		flib_map *newmap = flib_calloc(1, sizeof(flib_map));
+		if(newmap) {
+			newmap->mapgen = map->mapgen;
+			newmap->drawDataSize = map->drawDataSize;
+			newmap->drawData = flib_bufdupnull(map->drawData, map->drawDataSize);
+			newmap->mazeSize = map->mazeSize;
+			newmap->name = flib_strdupnull(map->name);
+			newmap->seed = flib_strdupnull(map->seed);
+			newmap->templateFilter = map->templateFilter;
+			newmap->theme = flib_strdupnull(map->theme);
+			if((newmap->drawData || !map->drawData) && (newmap->name || !map->name) && (newmap->seed || !map->seed) && (newmap->theme || !map->theme)) {
+				result = newmap;
+				newmap = NULL;
+			}
+		}
+		flib_map_destroy(newmap);
+	}
+	return result;
+}
+
+void flib_map_destroy(flib_map *map) {
+	if(map) {
+		free(map->seed);
+		free(map->drawData);
+		free(map->name);
+		free(map->theme);
+		free(map);
+	}
+}
diff --git a/project_files/frontlib/model/map.h b/project_files/frontlib/model/map.h
new file mode 100644
index 0000000..a6d0a85
--- /dev/null
+++ b/project_files/frontlib/model/map.h
@@ -0,0 +1,114 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef MODEL_MAP_H_
+#define MODEL_MAP_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#define MAPGEN_REGULAR 0
+#define MAPGEN_MAZE 1
+#define MAPGEN_DRAWN 2
+#define MAPGEN_NAMED 3
+
+#define TEMPLATEFILTER_ALL 0
+#define TEMPLATEFILTER_SMALL 1
+#define TEMPLATEFILTER_MEDIUM 2
+#define TEMPLATEFILTER_LARGE 3
+#define TEMPLATEFILTER_CAVERN 4
+#define TEMPLATEFILTER_WACKY 5
+
+#define MAZE_SIZE_SMALL_TUNNELS 0
+#define MAZE_SIZE_MEDIUM_TUNNELS 1
+#define MAZE_SIZE_LARGE_TUNNELS 2
+#define MAZE_SIZE_SMALL_ISLANDS 3
+#define MAZE_SIZE_MEDIUM_ISLANDS 4
+#define MAZE_SIZE_LARGE_ISLANDS 5
+
+/**
+ * Data structure for defining a map. This contains the whole recipe to
+ * exactly recreate a particular map.
+ *
+ * The required fields depend on the map generator, see the comments
+ * at the struct for details.
+ */
+typedef struct {
+	int mapgen;				//!< Always one of the MAPGEN_ constants
+	char *name;				//!< The name of the map for MAPGEN_NAMED (e.g. "Cogs"), otherwise one of "+rnd+", "+maze+" or "+drawn+".
+	char *seed;				//!< Used for all maps. This is a random seed for all (non-AI) entropy in the round. Typically a random UUID, but can be any string.
+	char *theme;			//!< Used for all maps. This is the name of a directory in Data/Themes (e.g. "Beach")
+	uint8_t *drawData;		//!< Used for MAPGEN_DRAWN
+	size_t drawDataSize;	//!< Used for MAPGEN_DRAWN
+	int templateFilter;		//!< Used for MAPGEN_REGULAR. One of the TEMPLATEFILTER_xxx constants.
+	int mazeSize;			//!< Used for MAPGEN_MAZE. One of the MAZE_SIZE_xxx constants.
+} flib_map;
+
+/**
+ * Create a generated map. theme should be the name of a
+ * directory in "Themes" and templateFilter should be one of the
+ * TEMPLATEFILTER_* constants, but this is not checked before
+ * passing it to the engine.
+ *
+ * Use flib_map_destroy to free the returned object.
+ * No NULL parameters allowed, returns NULL on failure.
+ */
+flib_map *flib_map_create_regular(const char *seed, const char *theme, int templateFilter);
+
+/**
+ * Create a generated maze-type map. theme should be the name of a
+ * directory in "Themes" and mazeSize should be one of the
+ * MAZE_SIZE_* constants, but this is not checked before
+ * passing it to the engine.
+ *
+ * Use flib_map_destroy to free the returned object.
+ * No NULL parameters allowed, returns NULL on failure.
+ */
+flib_map *flib_map_create_maze(const char *seed, const char *theme, int mazeSize);
+
+/**
+ * Create a map from the Maps-Directory. name should be the name of a
+ * directory in "Maps", but this is not checked before
+ * passing it to the engine. If this is a mission, the corresponding
+ * script is used automatically.
+ *
+ * Use flib_map_destroy to free the returned object.
+ * No NULL parameters allowed, returns NULL on failure.
+ */
+flib_map *flib_map_create_named(const char *seed, const char *name);
+
+/**
+ * Create a hand-drawn map. Use flib_map_destroy to free the returned object.
+ * No NULL parameters allowed, returns NULL on failure.
+ */
+flib_map *flib_map_create_drawn(const char *seed, const char *theme, const uint8_t *drawData, size_t drawDataSize);
+
+/**
+ * Create a deep copy of the map. Returns NULL on failure or if NULL was passed.
+ */
+flib_map *flib_map_copy(const flib_map *map);
+
+/**
+ * Decrease the reference count of the object and free it if this was the last reference.
+ */
+void flib_map_destroy(flib_map *map);
+
+
+#endif
diff --git a/project_files/frontlib/model/mapcfg.c b/project_files/frontlib/model/mapcfg.c
new file mode 100644
index 0000000..bdc64ec
--- /dev/null
+++ b/project_files/frontlib/model/mapcfg.c
@@ -0,0 +1,64 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "mapcfg.h"
+
+#include "../util/util.h"
+#include "../util/logging.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+void removeNewline(char *str) {
+	for(;*str;str++) {
+		if(*str=='\n' || *str=='\r') {
+			*str = 0;
+			return;
+		}
+	}
+}
+
+int flib_mapcfg_read(const char *dataDirPath, const char *mapname, flib_mapcfg *out) {
+	int result = -1;
+	if(!log_badargs_if4(dataDirPath==NULL, mapname==NULL, out==NULL, flib_contains_dir_separator(mapname))) {
+		char *path = flib_asprintf("%sMaps/%s/map.cfg", dataDirPath, mapname);
+		if(path) {
+			FILE *file = fopen(path, "rb");
+			if(!log_e_if(!file, "Unable to open map config file %s", path)) {
+				if(!log_e_if(!fgets(out->theme, sizeof(out->theme), file), "Error reading theme from %s", path)) {
+					removeNewline(out->theme);
+					char buf[64];
+					if(fgets(buf, sizeof(buf), file)) {
+						removeNewline(buf);
+						errno = 0;
+						out->hogLimit = strtol(buf, NULL, 10);
+						result = !log_e_if(errno, "Invalid hoglimit in %s: %i", path, buf);
+					} else {
+						result = 0;
+					}
+				}
+				fclose(file);
+			}
+		}
+		free(path);
+	}
+	return result;
+}
diff --git a/project_files/frontlib/model/mapcfg.h b/project_files/frontlib/model/mapcfg.h
new file mode 100644
index 0000000..a1c0a6e
--- /dev/null
+++ b/project_files/frontlib/model/mapcfg.h
@@ -0,0 +1,38 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/*!
+ * Data structure and functions for accessing the map.cfg of named maps.
+ */
+
+#ifndef MAPCFG_H_
+#define MAPCFG_H_
+
+typedef struct {
+	char theme[256];
+	int hogLimit;
+} flib_mapcfg;
+
+/**
+ * Read the map configuration for the map with this name.
+ * The dataDirPath must end in a path separator.
+ */
+int flib_mapcfg_read(const char *dataDirPath, const char *mapname, flib_mapcfg *out);
+
+#endif /* MAPCFG_H_ */
diff --git a/project_files/frontlib/model/room.c b/project_files/frontlib/model/room.c
new file mode 100644
index 0000000..c33cb83
--- /dev/null
+++ b/project_files/frontlib/model/room.c
@@ -0,0 +1,34 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "room.h"
+#include "../util/logging.h"
+
+#include <stdlib.h>
+
+void flib_room_destroy(flib_room *room) {
+	if(room) {
+		free(room->map);
+		free(room->name);
+		free(room->owner);
+		free(room->scheme);
+		free(room->weapons);
+		free(room);
+	}
+}
diff --git a/project_files/frontlib/model/room.h b/project_files/frontlib/model/room.h
new file mode 100644
index 0000000..df61b1c
--- /dev/null
+++ b/project_files/frontlib/model/room.h
@@ -0,0 +1,42 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/**
+ * Models the room information for the lobby roomlist.
+ */
+
+#ifndef ROOM_H_
+#define ROOM_H_
+
+#include <stdbool.h>
+
+typedef struct {
+    bool inProgress;	//!< true if the game is running
+    char *name;
+    int playerCount;
+    int teamCount;
+    char *owner;
+    char *map;			//!< This is either a map name, or one of +rnd+, +maze+ or +drawn+.
+    char *scheme;
+    char *weapons;
+} flib_room;
+
+void flib_room_destroy();
+
+#endif
diff --git a/project_files/frontlib/model/scheme.c b/project_files/frontlib/model/scheme.c
new file mode 100644
index 0000000..26a0dd6
--- /dev/null
+++ b/project_files/frontlib/model/scheme.c
@@ -0,0 +1,95 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "scheme.h"
+
+#include "../util/inihelper.h"
+#include "../util/logging.h"
+#include "../util/util.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+
+flib_scheme *flib_scheme_create(const char *schemeName) {
+	flib_scheme *result = flib_calloc(1, sizeof(flib_scheme));
+	if(log_badargs_if(schemeName==NULL) || result==NULL) {
+		return NULL;
+	}
+
+	result->name = flib_strdupnull(schemeName);
+	result->mods = flib_calloc(flib_meta.modCount, sizeof(*result->mods));
+	result->settings = flib_calloc(flib_meta.settingCount, sizeof(*result->settings));
+
+	if(!result->mods || !result->settings || !result->name) {
+		flib_scheme_destroy(result);
+		return NULL;
+	}
+
+	for(int i=0; i<flib_meta.settingCount; i++) {
+		result->settings[i] = flib_meta.settings[i].def;
+	}
+	return result;
+}
+
+flib_scheme *flib_scheme_copy(const flib_scheme *scheme) {
+	flib_scheme *result = NULL;
+	if(scheme) {
+		result = flib_scheme_create(scheme->name);
+		if(result) {
+			memcpy(result->mods, scheme->mods, flib_meta.modCount * sizeof(*scheme->mods));
+			memcpy(result->settings, scheme->settings, flib_meta.settingCount * sizeof(*scheme->settings));
+		}
+	}
+	return result;
+}
+
+void flib_scheme_destroy(flib_scheme* scheme) {
+	if(scheme) {
+		free(scheme->mods);
+		free(scheme->settings);
+		free(scheme->name);
+		free(scheme);
+	}
+}
+
+bool flib_scheme_get_mod(const flib_scheme *scheme, const char *name) {
+	if(!log_badargs_if2(scheme==NULL, name==NULL)) {
+		for(int i=0; i<flib_meta.modCount; i++) {
+			if(!strcmp(flib_meta.mods[i].name, name)) {
+				return scheme->mods[i];
+			}
+		}
+		flib_log_e("Unable to find game mod %s", name);
+	}
+	return false;
+}
+
+int flib_scheme_get_setting(const flib_scheme *scheme, const char *name, int def) {
+	if(!log_badargs_if2(scheme==NULL, name==NULL)) {
+		for(int i=0; i<flib_meta.settingCount; i++) {
+			if(!strcmp(flib_meta.settings[i].name, name)) {
+				return scheme->settings[i];
+			}
+		}
+		flib_log_e("Unable to find game setting %s", name);
+	}
+	return def;
+}
diff --git a/project_files/frontlib/model/scheme.h b/project_files/frontlib/model/scheme.h
new file mode 100644
index 0000000..b7891e4
--- /dev/null
+++ b/project_files/frontlib/model/scheme.h
@@ -0,0 +1,72 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/**
+ * Data structures for game scheme information.
+ *
+ * The scheme consists of settings (integers) and mods (booleans). These are not fixed, but
+ * described in a "metascheme", which describes how each setting and mod is sent to the
+ * engine, and in which order they appear in the network protocol. The metascheme is defined
+ * in hwconsts.h
+ */
+
+#ifndef SCHEME_H_
+#define SCHEME_H_
+
+#include <stdbool.h>
+#include <stddef.h>
+#include "../hwconsts.h"
+
+/**
+ * The settings and mods arrays have the same number and order of elements
+ * as the corresponding arrays in the metascheme.
+ */
+typedef struct {
+    char *name;
+    int *settings;
+    bool *mods;
+} flib_scheme;
+
+/**
+ * Create a new configuration with everything set to default or false
+ * Returns NULL on error.
+ */
+flib_scheme *flib_scheme_create(const char *schemeName);
+
+/**
+ * Create a copy of the scheme. Returns NULL on error or if NULL was passed.
+ */
+flib_scheme *flib_scheme_copy(const flib_scheme *scheme);
+
+/**
+ * Decrease the reference count of the object and free it if this was the last reference.
+ */
+void flib_scheme_destroy(flib_scheme* scheme);
+
+/**
+ * Retrieve a mod setting by its name. If the mod is not found, logs an error and returns false.
+ */
+bool flib_scheme_get_mod(const flib_scheme *scheme, const char *name);
+
+/**
+ * Retrieve a game setting by its name. If the setting is not found, logs an error and returns def.
+ */
+int flib_scheme_get_setting(const flib_scheme *scheme, const char *name, int def);
+
+#endif /* SCHEME_H_ */
diff --git a/project_files/frontlib/model/schemelist.c b/project_files/frontlib/model/schemelist.c
new file mode 100644
index 0000000..301ace8
--- /dev/null
+++ b/project_files/frontlib/model/schemelist.c
@@ -0,0 +1,216 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "schemelist.h"
+
+#include "../util/inihelper.h"
+#include "../util/logging.h"
+#include "../util/util.h"
+#include "../util/list.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+
+static char *makePrefixedName(int schemeIndex, const char *settingName) {
+	return flib_asprintf("%i\\%s", schemeIndex, settingName);
+}
+
+static int readSettingsFromIni(flib_ini *ini, flib_scheme *scheme, int index) {
+	bool error = false;
+	for(int i=0; i<flib_meta.settingCount && !error; i++) {
+		char *key = makePrefixedName(index, flib_meta.settings[i].name);
+		if(!key) {
+			error = true;
+		} else if(flib_ini_get_int_opt(ini, &scheme->settings[i], key, flib_meta.settings[i].def)) {
+			flib_log_e("Error reading setting %s in schemes file.", key);
+			error = true;
+		}
+		free(key);
+	}
+	return error;
+}
+
+static int readModsFromIni(flib_ini *ini, flib_scheme *scheme, int index) {
+	bool error = false;
+	for(int i=0; i<flib_meta.modCount && !error; i++) {
+		char *key = makePrefixedName(index, flib_meta.mods[i].name);
+		if(!key) {
+			error = true;
+		} else if(flib_ini_get_bool_opt(ini, &scheme->mods[i], key, false)) {
+			flib_log_e("Error reading mod %s in schemes file.", key);
+			error = true;
+		}
+		free(key);
+	}
+	return error;
+}
+
+static flib_scheme *readSchemeFromIni(flib_ini *ini, int index) {
+	flib_scheme *result = NULL;
+	char *schemeNameKey = makePrefixedName(index+1, "name");
+	if(schemeNameKey) {
+		char *schemeName = NULL;
+		if(!flib_ini_get_str_opt(ini, &schemeName, schemeNameKey, "Unnamed")) {
+			flib_scheme *tmpScheme = flib_scheme_create(schemeName);
+			if(tmpScheme) {
+				if(!readSettingsFromIni(ini, tmpScheme, index) && !readModsFromIni(ini, tmpScheme, index)) {
+					result = tmpScheme;
+					tmpScheme = NULL;
+				}
+			}
+			flib_scheme_destroy(tmpScheme);
+		}
+		free(schemeName);
+	}
+	free(schemeNameKey);
+	return result;
+}
+
+static flib_schemelist *fromIniHandleError(flib_schemelist *result, flib_ini *ini) {
+	flib_ini_destroy(ini);
+	flib_schemelist_destroy(result);
+	return NULL;
+}
+
+flib_schemelist *flib_schemelist_from_ini(const char *filename) {
+	if(log_badargs_if(filename==NULL)) {
+		return NULL;
+	}
+
+	flib_schemelist *list = NULL;
+	flib_ini *ini = flib_ini_load(filename);
+	if(!ini || flib_ini_enter_section(ini, "schemes")) {
+		flib_log_e("Missing file or missing section \"schemes\" in file %s.", filename);
+		return fromIniHandleError(list, ini);
+	}
+
+	list = flib_schemelist_create();
+	if(!list) {
+		return fromIniHandleError(list, ini);
+	}
+
+	int schemeCount = 0;
+	if(flib_ini_get_int(ini, &schemeCount, "size")) {
+		flib_log_e("Missing or malformed scheme count in config file %s.", filename);
+		return fromIniHandleError(list, ini);
+	}
+
+	for(int i=0; i<schemeCount; i++) {
+		flib_scheme *scheme = readSchemeFromIni(ini, i);
+		if(!scheme || flib_schemelist_insert(list, scheme, i)) {
+			flib_scheme_destroy(scheme);
+			flib_log_e("Error reading scheme %i from config file %s.", i, filename);
+			return fromIniHandleError(list, ini);
+		}
+	}
+
+
+	flib_ini_destroy(ini);
+	return list;
+}
+
+static int writeSchemeToIni(const flib_scheme *scheme, flib_ini *ini, int index) {
+	bool error = false;
+
+	char *key = makePrefixedName(index+1, "name");
+	error |= !key || flib_ini_set_str(ini, key, scheme->name);
+	free(key);
+
+	for(int i=0; i<flib_meta.modCount && !error; i++) {
+		char *key = makePrefixedName(index+1, flib_meta.mods[i].name);
+		error |= !key || flib_ini_set_bool(ini, key, scheme->mods[i]);
+		free(key);
+	}
+
+	for(int i=0; i<flib_meta.settingCount && !error; i++) {
+		char *key = makePrefixedName(index+1, flib_meta.settings[i].name);
+		error |= !key || flib_ini_set_int(ini, key, scheme->settings[i]);
+		free(key);
+	}
+	return error;
+}
+
+int flib_schemelist_to_ini(const char *filename, const flib_schemelist *schemes) {
+	int result = -1;
+	if(!log_badargs_if2(filename==NULL, schemes==NULL)) {
+		flib_ini *ini = flib_ini_create(NULL);
+		if(ini && !flib_ini_create_section(ini, "schemes")) {
+			bool error = false;
+			error |= flib_ini_set_int(ini, "size", schemes->schemeCount);
+			for(int i=0; i<schemes->schemeCount && !error; i++) {
+				error |= writeSchemeToIni(schemes->schemes[i], ini, i);
+			}
+
+			if(!error) {
+				result = flib_ini_save(ini, filename);
+			}
+		}
+		flib_ini_destroy(ini);
+	}
+	return result;
+}
+
+flib_schemelist *flib_schemelist_create() {
+	return flib_calloc(1, sizeof(flib_schemelist));
+}
+
+void flib_schemelist_destroy(flib_schemelist *list) {
+	if(list) {
+		for(int i=0; i<list->schemeCount; i++) {
+			flib_scheme_destroy(list->schemes[i]);
+		}
+		free(list->schemes);
+		free(list);
+	}
+}
+
+flib_scheme *flib_schemelist_find(flib_schemelist *list, const char *name) {
+	if(!log_badargs_if2(list==NULL, name==NULL)) {
+		for(int i=0; i<list->schemeCount; i++) {
+			if(!strcmp(name, list->schemes[i]->name)) {
+				return list->schemes[i];
+			}
+		}
+	}
+	return NULL;
+}
+
+GENERATE_STATIC_LIST_INSERT(insertScheme, flib_scheme*)
+GENERATE_STATIC_LIST_DELETE(deleteScheme, flib_scheme*)
+
+int flib_schemelist_insert(flib_schemelist *list, flib_scheme *cfg, int pos) {
+	if(!log_badargs_if2(list==NULL, cfg==NULL)
+			&& !insertScheme(&list->schemes, &list->schemeCount, cfg, pos)) {
+		return 0;
+	}
+	return -1;
+}
+
+int flib_schemelist_delete(flib_schemelist *list, int pos) {
+	if(!log_badargs_if(list==NULL)) {
+		flib_scheme *elem = list->schemes[pos];
+		if(!deleteScheme(&list->schemes, &list->schemeCount, pos)) {
+			flib_scheme_destroy(elem);
+			return 0;
+		}
+	}
+	return -1;
+}
diff --git a/project_files/frontlib/model/schemelist.h b/project_files/frontlib/model/schemelist.h
new file mode 100644
index 0000000..eedea4e
--- /dev/null
+++ b/project_files/frontlib/model/schemelist.h
@@ -0,0 +1,79 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/**
+ * Functions for managing a list of schemes.
+ * This is in here because the scheme config file of the QtFrontend (which we are staying compatible with) contains
+ * all the schemes at once, so we need functions to work with a list like that.
+ */
+
+#ifndef SCHEMELIST_H_
+#define SCHEMELIST_H_
+
+#include "scheme.h"
+
+typedef struct {
+	int schemeCount;
+	flib_scheme **schemes;
+} flib_schemelist;
+
+/**
+ * Load a list of configurations from the ini file.
+ * Returns NULL on error.
+ */
+flib_schemelist *flib_schemelist_from_ini(const char *filename);
+
+/**
+ * Store the list of configurations to an ini file.
+ * Returns NULL on error.
+ */
+int flib_schemelist_to_ini(const char *filename, const flib_schemelist *config);
+
+/**
+ * Create an empty scheme list. Returns NULL on error.
+ */
+flib_schemelist *flib_schemelist_create();
+
+/**
+ * Insert a new scheme into the list at position pos, moving all higher schemes to make place.
+ * pos must be at least 0 (insert at the start) and at most list->schemeCount (insert at the end).
+ * Ownership of the scheme is transferred to the list.
+ * Returns 0 on success.
+ */
+int flib_schemelist_insert(flib_schemelist *list, flib_scheme *cfg, int pos);
+
+/**
+ * Delete a scheme from the list at position pos, moving down all higher schemes.
+ * The scheme is destroyed.
+ * Returns 0 on success.
+ */
+int flib_schemelist_delete(flib_schemelist *list, int pos);
+
+/**
+ * Find the scheme with a specific name
+ */
+flib_scheme *flib_schemelist_find(flib_schemelist *list, const char *name);
+
+/**
+ * Free this schemelist and all contained schemes
+ */
+void flib_schemelist_destroy(flib_schemelist *list);
+
+
+#endif /* SCHEMELIST_H_ */
diff --git a/project_files/frontlib/model/team.c b/project_files/frontlib/model/team.c
new file mode 100644
index 0000000..4cec194
--- /dev/null
+++ b/project_files/frontlib/model/team.c
@@ -0,0 +1,323 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "team.h"
+
+#include "../util/inihelper.h"
+#include "../util/util.h"
+#include "../util/logging.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+static flib_team *from_ini_handleError(flib_team *result, flib_ini *settingfile) {
+	flib_ini_destroy(settingfile);
+	flib_team_destroy(result);
+	return NULL;
+}
+
+flib_team *flib_team_from_ini(const char *filename) {
+	if(log_badargs_if(filename==NULL)) {
+		return NULL;
+	}
+
+	flib_team *result = flib_calloc(1, sizeof(flib_team));
+	flib_ini *ini = NULL;
+
+	if(!result) {
+		return from_ini_handleError(result, ini);
+	}
+
+	ini = flib_ini_load(filename);
+	if(!ini) {
+		flib_log_e("Error loading team file %s", filename);
+		return from_ini_handleError(result, ini);
+	}
+
+	if(flib_ini_enter_section(ini, "team")) {
+		flib_log_e("Missing section \"Team\" in team file %s", filename);
+		return from_ini_handleError(result, ini);
+	}
+	bool error = false;
+	error |= flib_ini_get_str(ini, &result->name, "name");
+	error |= flib_ini_get_str(ini, &result->grave, "grave");
+	error |= flib_ini_get_str(ini, &result->fort, "fort");
+	error |= flib_ini_get_str(ini, &result->voicepack, "voicepack");
+	error |= flib_ini_get_str(ini, &result->flag, "flag");
+	error |= flib_ini_get_int(ini, &result->rounds, "rounds");
+	error |= flib_ini_get_int(ini, &result->wins, "wins");
+	error |= flib_ini_get_int(ini, &result->campaignProgress, "campaignprogress");
+
+	int difficulty = 0;
+	error |= flib_ini_get_int(ini, &difficulty, "difficulty");
+
+	if(error) {
+		flib_log_e("Missing or malformed entry in section \"Team\" in file %s", filename);
+		return from_ini_handleError(result, ini);
+	}
+
+	for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) {
+		char sectionName[32];
+		if(snprintf(sectionName, sizeof(sectionName), "hedgehog%i", i) <= 0) {
+			return from_ini_handleError(result, ini);
+		}
+		if(flib_ini_enter_section(ini, sectionName)) {
+			flib_log_e("Missing section \"%s\" in team file %s", sectionName, filename);
+			return from_ini_handleError(result, ini);
+		}
+		flib_hog *hog = &result->hogs[i];
+		error |= flib_ini_get_str(ini, &hog->name, "name");
+		error |= flib_ini_get_str(ini, &hog->hat, "hat");
+		error |= flib_ini_get_int(ini, &hog->rounds, "rounds");
+		error |= flib_ini_get_int(ini, &hog->kills, "kills");
+		error |= flib_ini_get_int(ini, &hog->deaths, "deaths");
+		error |= flib_ini_get_int(ini, &hog->suicides, "suicides");
+		result->hogs[i].difficulty = difficulty;
+		result->hogs[i].initialHealth = TEAM_DEFAULT_HEALTH;
+
+		if(error) {
+			flib_log_e("Missing or malformed entry in section \"%s\" in file %s", sectionName, filename);
+			return from_ini_handleError(result, ini);
+		}
+	}
+
+	if(!flib_ini_enter_section(ini, "binds")) {
+		result->bindingCount = flib_ini_get_keycount(ini);
+		if(result->bindingCount<0) {
+			flib_log_e("Error reading bindings from file %s", filename);
+			result->bindingCount = 0;
+		}
+		result->bindings = flib_calloc(result->bindingCount, sizeof(flib_binding));
+		if(!result->bindings) {
+			return from_ini_handleError(result, ini);
+		}
+		for(int i=0; i<result->bindingCount; i++) {
+			char *keyname = flib_ini_get_keyname(ini, i);
+			if(!keyname) {
+				error = true;
+			} else {
+				result->bindings[i].action = flib_urldecode(keyname);
+				error |= !result->bindings[i].action;
+				error |= flib_ini_get_str(ini, &result->bindings[i].binding, keyname);
+			}
+			free(keyname);
+		}
+	}
+
+	if(error) {
+		flib_log_e("Error reading team file %s", filename);
+		return from_ini_handleError(result, ini);
+	}
+
+	flib_ini_destroy(ini);
+	return result;
+}
+
+void flib_team_destroy(flib_team *team) {
+	if(team) {
+		for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) {
+			free(team->hogs[i].name);
+			free(team->hogs[i].hat);
+			flib_weaponset_destroy(team->hogs[i].weaponset);
+		}
+		free(team->name);
+		free(team->grave);
+		free(team->fort);
+		free(team->voicepack);
+		free(team->flag);
+		if(team->bindings) {
+			for(int i=0; i<team->bindingCount; i++) {
+				free(team->bindings[i].action);
+				free(team->bindings[i].binding);
+			}
+		}
+		free(team->bindings);
+		free(team->ownerName);
+		free(team);
+	}
+}
+
+static int writeTeamSection(const flib_team *team, flib_ini *ini) {
+	if(flib_ini_create_section(ini, "team")) {
+		return -1;
+	}
+	bool error = false;
+	error |= flib_ini_set_str(ini, "name",  team->name);
+	error |= flib_ini_set_str(ini, "grave", team->grave);
+	error |= flib_ini_set_str(ini, "fort", team->fort);
+	error |= flib_ini_set_str(ini, "voicepack", team->voicepack);
+	error |= flib_ini_set_str(ini, "flag", team->flag);
+	error |= flib_ini_set_int(ini, "rounds", team->rounds);
+	error |= flib_ini_set_int(ini, "wins", team->wins);
+	error |= flib_ini_set_int(ini, "campaignprogress", team->campaignProgress);
+	error |= flib_ini_set_int(ini, "difficulty", team->hogs[0].difficulty);
+	return error;
+}
+
+static int writeHogSections(const flib_team *team, flib_ini *ini) {
+	for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) {
+		const flib_hog *hog = &team->hogs[i];
+		char sectionName[32];
+		if(snprintf(sectionName, sizeof(sectionName), "hedgehog%i", i) <= 0) {
+			return -1;
+		}
+		if(flib_ini_create_section(ini, sectionName)) {
+			return -1;
+		}
+		bool error = false;
+		error |= flib_ini_set_str(ini, "name", hog->name);
+		error |= flib_ini_set_str(ini, "hat", hog->hat);
+		error |= flib_ini_set_int(ini, "rounds", hog->rounds);
+		error |= flib_ini_set_int(ini, "kills", hog->kills);
+		error |= flib_ini_set_int(ini, "deaths", hog->deaths);
+		error |= flib_ini_set_int(ini, "suicides", hog->suicides);
+		if(error) {
+			return error;
+		}
+	}
+	return 0;
+}
+
+static int writeBindingSection(const flib_team *team, flib_ini *ini) {
+	if(team->bindingCount == 0) {
+		return 0;
+	}
+	if(flib_ini_create_section(ini, "binds")) {
+		return -1;
+	}
+	for(int i=0; i<team->bindingCount; i++) {
+		bool error = false;
+		char *action = flib_urlencode(team->bindings[i].action);
+		if(action) {
+			error |= flib_ini_set_str(ini, action, team->bindings[i].binding);
+			free(action);
+		} else {
+			error = true;
+		}
+		if(error) {
+			return error;
+		}
+	}
+	return 0;
+}
+
+int flib_team_to_ini(const char *filename, const flib_team *team) {
+	int result = -1;
+	if(!log_badargs_if2(filename==NULL, team==NULL)) {
+		flib_ini *ini = flib_ini_create(filename);
+		bool error = false;
+		error |= writeTeamSection(team, ini);
+		error |= writeHogSections(team, ini);
+		error |= writeBindingSection(team, ini);
+		if(!error) {
+			result = flib_ini_save(ini, filename);
+		}
+		flib_ini_destroy(ini);
+	}
+	return result;
+}
+
+int flib_team_set_weaponset(flib_team *team, const flib_weaponset *set) {
+	if(team) {
+		for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) {
+			flib_weaponset_destroy(team->hogs[i].weaponset);
+			team->hogs[i].weaponset = flib_weaponset_copy(set);
+			if(set && !team->hogs[i].weaponset) {
+				return -1;
+			}
+		}
+	}
+	return 0;
+}
+
+void flib_team_set_health(flib_team *team, int health) {
+	if(team) {
+		for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) {
+			team->hogs[i].initialHealth = health;
+		}
+	}
+}
+
+static char *strdupWithError(const char *in, bool *error) {
+	char *out = flib_strdupnull(in);
+	if(in && !out) {
+		*error = true;
+	}
+	return out;
+}
+
+flib_team *flib_team_copy(const flib_team *team) {
+	flib_team *result = NULL;
+	if(team) {
+		flib_team *tmpTeam = flib_calloc(1, sizeof(flib_team));
+		if(tmpTeam) {
+			bool error = false;
+
+			for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) {
+				tmpTeam->hogs[i].name = strdupWithError(team->hogs[i].name, &error);
+				tmpTeam->hogs[i].hat = strdupWithError(team->hogs[i].hat, &error);
+				tmpTeam->hogs[i].rounds = team->hogs[i].rounds;
+				tmpTeam->hogs[i].kills = team->hogs[i].kills;
+				tmpTeam->hogs[i].deaths = team->hogs[i].deaths;
+				tmpTeam->hogs[i].suicides = team->hogs[i].suicides;
+				tmpTeam->hogs[i].difficulty = team->hogs[i].difficulty;
+				tmpTeam->hogs[i].initialHealth = team->hogs[i].initialHealth;
+				tmpTeam->hogs[i].weaponset = flib_weaponset_copy(team->hogs[i].weaponset);
+				if(team->hogs[i].weaponset && !tmpTeam->hogs[i].weaponset) {
+					error = true;
+				}
+			}
+
+			tmpTeam->name = strdupWithError(team->name, &error);
+			tmpTeam->grave = strdupWithError(team->grave, &error);
+			tmpTeam->fort = strdupWithError(team->fort, &error);
+			tmpTeam->voicepack = strdupWithError(team->voicepack, &error);
+			tmpTeam->flag = strdupWithError(team->flag, &error);
+			tmpTeam->ownerName = strdupWithError(team->ownerName, &error);
+
+			tmpTeam->bindingCount = team->bindingCount;
+			if(team->bindings) {
+				tmpTeam->bindings = flib_calloc(team->bindingCount, sizeof(flib_binding));
+				if(tmpTeam->bindings) {
+					for(int i=0; i<tmpTeam->bindingCount; i++) {
+						tmpTeam->bindings[i].action = strdupWithError(team->bindings[i].action, &error);
+						tmpTeam->bindings[i].binding = strdupWithError(team->bindings[i].binding, &error);
+					}
+				} else {
+					error = true;
+				}
+			}
+
+			tmpTeam->rounds = team->rounds;
+			tmpTeam->wins = team->wins;
+			tmpTeam->campaignProgress = team->campaignProgress;
+
+			tmpTeam->colorIndex = team->colorIndex;
+			tmpTeam->hogsInGame = team->hogsInGame;
+			tmpTeam->remoteDriven = team->remoteDriven;
+
+			if(!error) {
+				result = tmpTeam;
+				tmpTeam = 0;
+			}
+		}
+		flib_team_destroy(tmpTeam);
+	}
+	return result;
+}
diff --git a/project_files/frontlib/model/team.h b/project_files/frontlib/model/team.h
new file mode 100644
index 0000000..01a8456
--- /dev/null
+++ b/project_files/frontlib/model/team.h
@@ -0,0 +1,130 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/**
+ * This file defines a data structure for a hedgewars team.
+ *
+ * Teams are used in several different contexts in Hedgewars, and some of these require
+ * extra information about teams. For example, the weaponset is important
+ * to the engine, but not for ini reading/writing, and with the team statistics it is the
+ * other way around. To keep things simple, the data structure can hold all information
+ * used in any context. On the downside, that means we can't use static typing to ensure
+ * that team information is "complete" for a particular purpose.
+ */
+#ifndef TEAM_H_
+#define TEAM_H_
+
+
+#include "weapon.h"
+#include "../hwconsts.h"
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#define TEAM_DEFAULT_HEALTH 100
+
+/**
+ * Struct representing a single keybinding.
+ */
+typedef struct {
+	char *action;
+	char *binding;
+} flib_binding;
+
+typedef struct {
+	char *name;
+	char *hat;			//!< e.g. hair_yellow; References a .png file in Data/Graphics/Hats
+
+	//! Statistics. They are irrelevant for the engine or server,
+	//! but provided for ini reading/writing by the frontend.
+	int rounds;
+	int kills;
+	int deaths;
+	int suicides;
+
+	int difficulty;		//!< 0 = human, 1 = most difficult bot ... 5 = least difficult bot (somewhat counterintuitive)
+
+	//! Transient setting used in game setup
+	int initialHealth;
+	flib_weaponset *weaponset;
+} flib_hog;
+
+typedef struct {
+	flib_hog hogs[HEDGEHOGS_PER_TEAM];
+	char *name;
+	char *grave;		//!< e.g. "Bone"; References a .png file in Data/Graphics/Graves
+	char *fort;			//!< e.g. "Castle"; References a series of files in Data/Forts
+	char *voicepack;	//!< e.g. "Classic"; References a directory in Data/Sounds/voices
+	char *flag;			//!< e.g. "hedgewars"; References a .png file in Data/Graphics/Flags
+
+	flib_binding *bindings;
+	int bindingCount;
+
+	//! Statistics. They are irrelevant for the engine or server,
+	//! but provided for ini reading/writing by the frontend.
+	int rounds;
+	int wins;
+	int campaignProgress;
+
+	//! Transient settings used in game setup
+	int colorIndex;		//!< Index into a color table
+	int hogsInGame;		//!< The number of hogs that will actually play
+	bool remoteDriven;	//!< true for non-local teams in a network game
+	char *ownerName;	//!< Username of the owner of a team in a network game
+} flib_team;
+
+/**
+ * Free all memory associated with the team
+ */
+void flib_team_destroy(flib_team *team);
+
+/**
+ * Loads a team, returns NULL on error. Destroy this team using flib_team_destroy.
+ * This will not fill in the fields marked as "transient" in the structs above.
+ */
+flib_team *flib_team_from_ini(const char *filename);
+
+/**
+ * Write the team to an ini file. Attempts to retain extra ini settings
+ * that were already present. Note that not all fields of a team struct
+ * are stored in the ini, some are only used intermittently to store
+ * information about a team in the context of a game.
+ *
+ * The flib_team can handle "difficulty" on a per-hog basis, but it
+ * is only written per-team in the team file. The difficulty of the
+ * first hog is used for the entire team when writing.
+ */
+int flib_team_to_ini(const char *filename, const flib_team *team);
+
+/**
+ * Set the same weaponset for every hog in the team
+ */
+int flib_team_set_weaponset(flib_team *team, const flib_weaponset *set);
+
+/**
+ * Set the same initial health for every hog.
+ */
+void flib_team_set_health(flib_team *team, int health);
+
+/**
+ * Create a deep copy of a team. Returns NULL on failure.
+ */
+flib_team *flib_team_copy(const flib_team *team);
+
+#endif /* TEAM_H_ */
diff --git a/project_files/frontlib/model/teamlist.c b/project_files/frontlib/model/teamlist.c
new file mode 100644
index 0000000..b513579
--- /dev/null
+++ b/project_files/frontlib/model/teamlist.c
@@ -0,0 +1,120 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "teamlist.h"
+
+#include "../util/util.h"
+#include "../util/list.h"
+#include "../util/logging.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+flib_teamlist *flib_teamlist_create() {
+	return flib_calloc(1, sizeof(flib_teamlist));
+}
+
+void flib_teamlist_destroy(flib_teamlist *list) {
+	if(list) {
+		for(int i=0; i<list->teamCount; i++) {
+			flib_team_destroy(list->teams[i]);
+		}
+		free(list->teams);
+		free(list);
+	}
+}
+
+GENERATE_STATIC_LIST_INSERT(insertTeam, flib_team*)
+GENERATE_STATIC_LIST_DELETE(deleteTeam, flib_team*)
+
+static int findTeam(const flib_teamlist *list, const char *name) {
+	for(int i=0; i<list->teamCount; i++) {
+		if(!strcmp(name, list->teams[i]->name)) {
+			return i;
+		}
+	}
+	return -1;
+}
+
+int flib_teamlist_insert(flib_teamlist *list, flib_team *team, int pos) {
+	if(!log_badargs_if2(list==NULL, team==NULL)
+			&& !insertTeam(&list->teams, &list->teamCount, team, pos)) {
+		return 0;
+	}
+	return -1;
+}
+
+int flib_teamlist_delete(flib_teamlist *list, const char *name) {
+	int result = -1;
+	if(!log_badargs_if2(list==NULL, name==NULL)) {
+		int itemid = findTeam(list, name);
+		if(itemid>=0) {
+			flib_team *team = list->teams[itemid];
+			if(!deleteTeam(&list->teams, &list->teamCount, itemid)) {
+				flib_team_destroy(team);
+				result = 0;
+			}
+		}
+	}
+	return result;
+}
+
+flib_team *flib_teamlist_find(const flib_teamlist *list, const char *name) {
+	flib_team *result = NULL;
+	if(!log_badargs_if2(list==NULL, name==NULL)) {
+		int itemid = findTeam(list, name);
+		if(itemid>=0) {
+			result = list->teams[itemid];
+		}
+	}
+	return result;
+}
+
+void flib_teamlist_clear(flib_teamlist *list) {
+	if(!log_badargs_if(list==NULL)) {
+		for(int i=0; i<list->teamCount; i++) {
+			flib_team_destroy(list->teams[i]);
+		}
+		free(list->teams);
+		list->teams = NULL;
+		list->teamCount = 0;
+	}
+}
+
+flib_teamlist *flib_teamlist_copy(flib_teamlist *list) {
+	if(!list) {
+		return NULL;
+	}
+	flib_teamlist *result = flib_teamlist_create();
+	if(result) {
+		bool error = false;
+		for(int i=0; !error && i<list->teamCount; i++) {
+			flib_team *teamcopy = flib_team_copy(list->teams[i]);
+			if(!teamcopy || flib_teamlist_insert(result, teamcopy, i)) {
+				flib_team_destroy(teamcopy);
+				error = true;
+			}
+		}
+		if(error) {
+			flib_teamlist_destroy(result);
+			result = NULL;
+		}
+	}
+	return result;
+}
diff --git a/project_files/frontlib/model/teamlist.h b/project_files/frontlib/model/teamlist.h
new file mode 100644
index 0000000..7ce5e90
--- /dev/null
+++ b/project_files/frontlib/model/teamlist.h
@@ -0,0 +1,61 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef TEAMLIST_H_
+#define TEAMLIST_H_
+
+#include "team.h"
+
+typedef struct {
+	int teamCount;
+	flib_team **teams;
+} flib_teamlist;
+
+flib_teamlist *flib_teamlist_create();
+
+void flib_teamlist_destroy(flib_teamlist *list);
+
+/**
+ * Insert a team into the list. The list takes ownership of the team. Returns 0 on success.
+ */
+int flib_teamlist_insert(flib_teamlist *list, flib_team *team, int pos);
+
+/**
+ * Delete the team with the name [name] from the list and destroys it.
+ * Returns 0 on success.
+ */
+int flib_teamlist_delete(flib_teamlist *list, const char *name);
+
+/**
+ * Returns the team with the name [name] from the list if it exists, NULL otherwise
+ */
+flib_team *flib_teamlist_find(const flib_teamlist *list, const char *name);
+
+/**
+ * Removes all items from the list and destroys them.
+ */
+void flib_teamlist_clear(flib_teamlist *list);
+
+/**
+ * Create a copy of the list and all the teams it contains. Weaponsets are not copied, but
+ * kept as references
+ */
+flib_teamlist *flib_teamlist_copy(flib_teamlist *list);
+
+#endif
diff --git a/project_files/frontlib/model/weapon.c b/project_files/frontlib/model/weapon.c
new file mode 100644
index 0000000..3c22212
--- /dev/null
+++ b/project_files/frontlib/model/weapon.c
@@ -0,0 +1,234 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "weapon.h"
+
+#include "../util/inihelper.h"
+#include "../util/logging.h"
+#include "../util/util.h"
+#include "../util/list.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+static void setField(char field[WEAPONS_COUNT+1], const char *line, int lineLen, bool no9) {
+	if(lineLen>WEAPONS_COUNT) {
+		lineLen = WEAPONS_COUNT;
+	}
+
+	char min = '0';
+	char max = no9 ? '8' : '9';
+	for(int i=0; i<lineLen; i++) {
+		if(line[i] >= min && line[i] <= max) {
+			field[i] = line[i];
+		} else {
+			flib_log_w("Invalid character in weapon config string \"%.*s\", position %i", lineLen, line, i);
+			field[i] = '0';
+		}
+	}
+	for(int i=lineLen; i<WEAPONS_COUNT; i++) {
+		field[i] = '0';
+	}
+	field[WEAPONS_COUNT] = 0;
+}
+
+flib_weaponset *flib_weaponset_create(const char *name) {
+	flib_weaponset *result = NULL;
+	if(!log_badargs_if(name==NULL)) {
+		flib_weaponset *newSet = flib_calloc(1, sizeof(flib_weaponset));
+		if(newSet) {
+			newSet->name = flib_strdupnull(name);
+			if(newSet->name) {
+				setField(newSet->loadout, "", 0, false);
+				setField(newSet->crateprob, "", 0, false);
+				setField(newSet->crateammo, "", 0, false);
+				setField(newSet->delay, "", 0, false);
+				result = newSet;
+				newSet = NULL;
+			}
+		}
+		flib_weaponset_destroy(newSet);
+	}
+	return result;
+}
+
+void flib_weaponset_destroy(flib_weaponset *cfg) {
+	if(cfg) {
+		free(cfg->name);
+		free(cfg);
+	}
+}
+
+flib_weaponset *flib_weaponset_copy(const flib_weaponset *weaponset) {
+	if(!weaponset) {
+		return NULL;
+	}
+
+	flib_weaponset *result = flib_weaponset_create(weaponset->name);
+	if(result) {
+		memcpy(result->loadout, weaponset->loadout, WEAPONS_COUNT+1);
+		memcpy(result->crateprob, weaponset->crateprob, WEAPONS_COUNT+1);
+		memcpy(result->delay, weaponset->delay, WEAPONS_COUNT+1);
+		memcpy(result->crateammo, weaponset->crateammo, WEAPONS_COUNT+1);
+	}
+
+	return result;
+}
+
+void flib_weaponsetlist_destroy(flib_weaponsetlist *list) {
+	if(list) {
+		for(int i=0; i<list->weaponsetCount; i++) {
+			flib_weaponset_destroy(list->weaponsets[i]);
+		}
+		free(list->weaponsets);
+		free(list);
+	}
+}
+
+flib_weaponset *flib_weaponset_from_ammostring(const char *name, const char *ammostring) {
+	flib_weaponset *result = NULL;
+	if(!log_badargs_if2(name==NULL, ammostring==NULL)) {
+		result = flib_weaponset_create(name);
+		if(result) {
+			int fieldlen = strlen(ammostring)/4;
+			setField(result->loadout, ammostring, fieldlen, false);
+			setField(result->crateprob, ammostring + fieldlen, fieldlen, true);
+			setField(result->delay, ammostring + 2*fieldlen, fieldlen, true);
+			setField(result->crateammo, ammostring + 3*fieldlen, fieldlen, true);
+		}
+	}
+	return result;
+}
+
+static int fillWeaponsetFromIni(flib_weaponsetlist *list, flib_ini *ini, int index) {
+	int result = -1;
+	char *keyname = flib_ini_get_keyname(ini, index);
+	char *decodedKeyname = flib_urldecode(keyname);
+	char *ammostring = NULL;
+	if(decodedKeyname && !flib_ini_get_str(ini, &ammostring, keyname)) {
+		flib_weaponset *set = flib_weaponset_from_ammostring(decodedKeyname, ammostring);
+		if(set) {
+			result = flib_weaponsetlist_insert(list, set, list->weaponsetCount);
+			if(result) {
+				flib_weaponset_destroy(set);
+			}
+		}
+	}
+	free(ammostring);
+	free(decodedKeyname);
+	free(keyname);
+	return result;
+}
+
+static int fillWeaponsetsFromIni(flib_weaponsetlist *list, flib_ini *ini) {
+	bool error = false;
+	int weaponsets = flib_ini_get_keycount(ini);
+
+	for(int i=0; i<weaponsets && !error; i++) {
+		error |= fillWeaponsetFromIni(list, ini, i);
+	}
+	return error;
+}
+
+flib_weaponsetlist *flib_weaponsetlist_from_ini(const char *filename) {
+	flib_weaponsetlist *result = NULL;
+	if(!log_badargs_if(filename==NULL)) {
+		flib_ini *ini = flib_ini_load(filename);
+		if(!ini) {
+			flib_log_e("Missing file %s.", filename);
+		} else if(flib_ini_enter_section(ini, "General")) {
+			flib_log_e("Missing section \"General\" in file %s.", filename);
+		} else {
+			flib_weaponsetlist *tmpList = flib_weaponsetlist_create();
+			if(tmpList && !fillWeaponsetsFromIni(tmpList, ini)) {
+				result = tmpList;
+				tmpList = NULL;
+			}
+			flib_weaponsetlist_destroy(tmpList);
+		}
+		flib_ini_destroy(ini);
+	}
+	return result;
+}
+
+static bool needsEscape(char c) {
+	return !((c>='0' && c<='9') || (c>='a' && c <='z'));
+}
+
+static int writeWeaponsetToIni(flib_ini *ini, flib_weaponset *set) {
+	int result = -1;
+	char weaponstring[WEAPONS_COUNT*4+1];
+	strcpy(weaponstring, set->loadout);
+	strcat(weaponstring, set->crateprob);
+	strcat(weaponstring, set->delay);
+	strcat(weaponstring, set->crateammo);
+
+	char *escapedname = flib_urlencode_pred(set->name, needsEscape);
+	if(escapedname) {
+		result = flib_ini_set_str(ini, escapedname, weaponstring);
+	}
+	free(escapedname);
+	return result;
+}
+
+int flib_weaponsetlist_to_ini(const char *filename, const flib_weaponsetlist *list) {
+	int result = -1;
+	if(!log_badargs_if2(filename==NULL, list==NULL)) {
+		flib_ini *ini = flib_ini_create(NULL);
+		if(ini && !flib_ini_create_section(ini, "General")) {
+			bool error = false;
+			for(int i=0; i<list->weaponsetCount && !error; i++) {
+				error |= writeWeaponsetToIni(ini, list->weaponsets[i]);
+			}
+
+			if(!error) {
+				result = flib_ini_save(ini, filename);
+			}
+		}
+		flib_ini_destroy(ini);
+	}
+	return result;
+}
+
+flib_weaponsetlist *flib_weaponsetlist_create() {
+	return flib_calloc(1, sizeof(flib_weaponsetlist));
+}
+
+GENERATE_STATIC_LIST_INSERT(insertWeaponset, flib_weaponset*)
+GENERATE_STATIC_LIST_DELETE(deleteWeaponset, flib_weaponset*)
+
+int flib_weaponsetlist_insert(flib_weaponsetlist *list, flib_weaponset *set, int pos) {
+	if(!log_badargs_if2(list==NULL, set==NULL)
+			&& !insertWeaponset(&list->weaponsets, &list->weaponsetCount, set, pos)) {
+		return 0;
+	}
+	return -1;
+}
+
+int flib_weaponsetlist_delete(flib_weaponsetlist *list, int pos) {
+	if(!log_badargs_if(list==NULL)) {
+		flib_weaponset *elem = list->weaponsets[pos];
+		if(!deleteWeaponset(&list->weaponsets, &list->weaponsetCount, pos)) {
+			flib_weaponset_destroy(elem);
+			return 0;
+		}
+	}
+	return -1;
+}
diff --git a/project_files/frontlib/model/weapon.h b/project_files/frontlib/model/weapon.h
new file mode 100644
index 0000000..f918d19
--- /dev/null
+++ b/project_files/frontlib/model/weapon.h
@@ -0,0 +1,104 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef MODEL_WEAPON_H_
+#define MODEL_WEAPON_H_
+
+#include "../hwconsts.h"
+
+/**
+ * These values are all ASCII characters in the range '0'..'9'
+ * The fields are zero-terminated so they can easily be used as strings.
+ *
+ * For loadout, 9 means inifinite ammo.
+ * For the other setting, 9 is invalid.
+ */
+typedef struct {
+	char loadout[WEAPONS_COUNT+1];
+	char crateprob[WEAPONS_COUNT+1];
+	char crateammo[WEAPONS_COUNT+1];
+	char delay[WEAPONS_COUNT+1];
+	char *name;
+} flib_weaponset;
+
+typedef struct {
+	int weaponsetCount;
+	flib_weaponset **weaponsets;
+} flib_weaponsetlist;
+
+/**
+ * Returns a new weapon set, or NULL on error.
+ * name must not be NULL.
+ *
+ * The new weapon set is pre-filled with default
+ * settings (see hwconsts.h)
+ */
+flib_weaponset *flib_weaponset_create(const char *name);
+
+/**
+ * Free the memory used by this weaponset
+ */
+void flib_weaponset_destroy(flib_weaponset *weaponset);
+
+flib_weaponset *flib_weaponset_copy(const flib_weaponset *weaponset);
+
+/**
+ * Create a weaponset from an ammostring. This format is used both in the ini files
+ * and in the net protocol.
+ */
+flib_weaponset *flib_weaponset_from_ammostring(const char *name, const char *ammostring);
+
+/**
+ * Load a list of weaponsets from the ini file.
+ * Returns NULL on error.
+ */
+flib_weaponsetlist *flib_weaponsetlist_from_ini(const char *filename);
+
+/**
+ * Store the list of weaponsets to an ini file.
+ * Returns NULL on error.
+ */
+int flib_weaponsetlist_to_ini(const char *filename, const flib_weaponsetlist *weaponsets);
+
+/**
+ * Create an empty weaponset list. Returns NULL on error.
+ */
+flib_weaponsetlist *flib_weaponsetlist_create();
+
+/**
+ * Release all memory associated with the weaponsetlist and release all contained weaponsets
+ */
+void flib_weaponsetlist_destroy(flib_weaponsetlist *list);
+
+/**
+ * Insert a new weaponset into the list at position pos, moving all higher weaponsets to make place.
+ * pos must be at least 0 (insert at the start) and at most list->weaponsetCount (insert at the end).
+ * Ownership of the weaponset is transferred to the list.
+ * Returns 0 on success.
+ */
+int flib_weaponsetlist_insert(flib_weaponsetlist *list, flib_weaponset *weaponset, int pos);
+
+/**
+ * Delete a weaponset from the list at position pos, moving down all higher weaponsets.
+ * The weaponset is destroyed.
+ * Returns 0 on success.
+ */
+int flib_weaponsetlist_delete(flib_weaponsetlist *list, int pos);
+
+#endif
diff --git a/project_files/frontlib/net/netbase.c b/project_files/frontlib/net/netbase.c
new file mode 100644
index 0000000..968ec89
--- /dev/null
+++ b/project_files/frontlib/net/netbase.c
@@ -0,0 +1,259 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "netbase.h"
+#include "../util/buffer.h"
+#include "../util/logging.h"
+#include "../util/util.h"
+#include "../socket.h"
+
+#include <string.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#define NET_READBUFFER_LIMIT (1024*1024)
+
+struct _flib_netbase {
+	flib_vector *readBuffer;
+	flib_tcpsocket *sock;
+};
+
+flib_netbase *flib_netbase_create(const char *server, uint16_t port) {
+	if(log_badargs_if2(server==NULL, port==0)) {
+		return NULL;
+	}
+
+	flib_netbase *result = NULL;
+	flib_netbase *newNet =  flib_calloc(1, sizeof(flib_netbase));
+
+	if(newNet) {
+		newNet->readBuffer = flib_vector_create();
+		newNet->sock = flib_socket_connect(server, port);
+		if(newNet->readBuffer && newNet->sock) {
+			flib_log_i("Connected to server %s:%u", server, (unsigned)port);
+			result = newNet;
+			newNet = NULL;
+		}
+	}
+	flib_netbase_destroy(newNet);
+
+	return result;
+}
+
+void flib_netbase_destroy(flib_netbase *net) {
+	if(net) {
+		flib_socket_close(net->sock);
+		flib_vector_destroy(net->readBuffer);
+		free(net);
+	}
+}
+
+bool flib_netbase_connected(flib_netbase *net) {
+	if(!log_badargs_if(net==NULL) && net->sock) {
+		return true;
+	}
+	return false;
+}
+
+/**
+ * Parses and returns a message, and removes it from the vector.
+ */
+static flib_netmsg *parseMessage(flib_vector *vec) {
+	const uint8_t *partStart = flib_vector_data(vec);
+	const uint8_t *end = partStart+flib_vector_size(vec);
+	flib_netmsg *result = flib_netmsg_create();
+	if(!result) {
+		return NULL;
+	}
+
+	while(1) {
+		const uint8_t *partEnd = memchr(partStart, '\n', end-partStart);
+		if(!partEnd) {
+			// message incomplete
+			flib_netmsg_destroy(result);
+			return NULL;
+		} else if(partEnd-partStart == 0) {
+			// Zero-length part, message end marker. Remove the message from the vector.
+			uint8_t *vectorStart = flib_vector_data(vec);
+			size_t msgLen = partEnd+1-vectorStart;
+			memmove(vectorStart, partEnd+1, flib_vector_size(vec)-msgLen);
+			flib_vector_resize(vec, flib_vector_size(vec)-msgLen);
+			return result;
+		} else {
+			if(flib_netmsg_append_part(result, partStart, partEnd-partStart)) {
+				flib_netmsg_destroy(result);
+				return NULL;
+			}
+			partStart = partEnd+1; // Skip the '\n'
+		}
+	}
+	return NULL; // Never reached
+}
+
+/**
+ * Receive some bytes and add them to the buffer.
+ * Returns the number of bytes received.
+ * Automatically closes the socket if an error occurs
+ * and sets sock=NULL.
+ */
+static int receiveToBuffer(flib_netbase *net) {
+	uint8_t buffer[256];
+	if(!net->sock) {
+		return 0;
+	} else if(flib_vector_size(net->readBuffer) > NET_READBUFFER_LIMIT) {
+		flib_log_e("Net connection closed: Net message too big");
+		flib_socket_close(net->sock);
+		net->sock = NULL;
+		return 0;
+	} else {
+		int size = flib_socket_nbrecv(net->sock, buffer, sizeof(buffer));
+		if(size>=0 && !flib_vector_append(net->readBuffer, buffer, size)) {
+			return size;
+		} else {
+			flib_socket_close(net->sock);
+			net->sock = NULL;
+			return 0;
+		}
+	}
+}
+
+flib_netmsg *flib_netbase_recv_message(flib_netbase *net) {
+	if(log_badargs_if(net==NULL)) {
+		return NULL;
+	}
+
+	flib_netmsg *msg;
+	while(!(msg=parseMessage(net->readBuffer))
+			&& receiveToBuffer(net)) {}
+
+	if(msg) {
+		return msg;
+	} else if(!net->sock && flib_vector_size(net->readBuffer)>0) {
+		// Connection is down and we didn't get a complete message, just flush the rest.
+		flib_vector_resize(net->readBuffer, 0);
+	}
+	return NULL;
+}
+
+static void logSentMsg(const uint8_t *data, size_t len) {
+	if(flib_log_isActive(FLIB_LOGLEVEL_DEBUG)) {
+		flib_log_d("[NET OUT][%03u]%*.*s",(unsigned)len, (unsigned)len, (unsigned)len, data);
+	}
+}
+
+int flib_netbase_send_raw(flib_netbase *net, const void *data, size_t len) {
+	if(log_badargs_if2(net==NULL, data==NULL && len>0)) {
+		return -1;
+	}
+	if(!net->sock) {
+		flib_log_w("flib_netbase_send_raw: Not connected.");
+		return -1;
+	}
+
+	if(flib_socket_send(net->sock, data, len) == len) {
+		logSentMsg(data, len);
+		return 0;
+	} else {
+		flib_log_w("Failed or incomplete write: net connection lost.");
+		flib_socket_close(net->sock);
+		net->sock = NULL;
+		return -1;
+	}
+}
+
+int flib_netbase_send_message(flib_netbase *net, const flib_netmsg *msg) {
+	if(log_badargs_if2(net==NULL, msg==NULL)) {
+		return -1;
+	}
+
+	size_t totalSize = 0;
+	for(int i=0; i<msg->partCount; i++) {
+		totalSize += strlen(msg->parts[i]) + 1;
+	}
+	totalSize++; // Last part ends in two '\n' instead of one
+
+	uint8_t *buffer = flib_malloc(totalSize);
+	if(!buffer) {
+		return -1;
+	}
+	size_t pos = 0;
+	for(int i=0; i<msg->partCount; i++) {
+		size_t partsize = strlen(msg->parts[i]);
+		memcpy(buffer+pos, msg->parts[i], partsize);
+		pos += partsize;
+		buffer[pos++] = '\n';
+	}
+	buffer[pos++] = '\n';
+	return flib_netbase_send_raw(net, buffer, pos);
+}
+
+int flib_netbase_sendf(flib_netbase *net, const char *format, ...) {
+	int result = -1;
+	if(!log_badargs_if2(net==NULL, format==NULL)) {
+		va_list argp;
+		va_start(argp, format);
+		char *buffer = flib_vasprintf(format, argp);
+		if(buffer) {
+			result = flib_netbase_send_raw(net, buffer, strlen(buffer));
+		}
+		free(buffer);
+		va_end(argp);
+	}
+	return result;
+}
+
+flib_netmsg *flib_netmsg_create() {
+	flib_netmsg *result = flib_calloc(1, sizeof(flib_netmsg));
+	if(result) {
+		result->partCount = 0;
+		result->parts = NULL;
+		return result;
+	} else {
+		return NULL;
+	}
+}
+
+void flib_netmsg_destroy(flib_netmsg *msg) {
+	if(msg) {
+		for(int i=0; i<msg->partCount; i++) {
+			free(msg->parts[i]);
+		}
+		free(msg->parts);
+		free(msg);
+	}
+}
+
+int flib_netmsg_append_part(flib_netmsg *msg, const void *part, size_t partlen) {
+	int result = -1;
+	if(!log_badargs_if2(msg==NULL, part==NULL && partlen>0)) {
+		char **newParts = realloc(msg->parts, (msg->partCount+1)*sizeof(*msg->parts));
+		if(newParts) {
+			msg->parts = newParts;
+			msg->parts[msg->partCount] = flib_malloc(partlen+1);
+			if(msg->parts[msg->partCount]) {
+				memcpy(msg->parts[msg->partCount], part, partlen);
+				msg->parts[msg->partCount][partlen] = 0;
+				msg->partCount++;
+				result = 0;
+			}
+		}
+	}
+	return result;
+}
diff --git a/project_files/frontlib/net/netbase.h b/project_files/frontlib/net/netbase.h
new file mode 100644
index 0000000..8fa8a09
--- /dev/null
+++ b/project_files/frontlib/net/netbase.h
@@ -0,0 +1,91 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/*
+ * Low-level protocol support for the network connection
+ */
+
+#ifndef NETBASE_H_
+#define NETBASE_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+struct _flib_netbase;
+typedef struct _flib_netbase flib_netbase;
+
+typedef struct {
+	int partCount;
+	char **parts;
+} flib_netmsg;
+
+/**
+ * Start a connection to the specified Hedgewars server.
+ *
+ * Returns NULL on error. Destroy the created object with flib_netconn_destroy.
+ */
+flib_netbase *flib_netbase_create(const char *server, uint16_t port);
+
+/**
+ * Free resources and close sockets.
+ */
+void flib_netbase_destroy(flib_netbase *net);
+
+/**
+ * Determine the current connection state. Starts out true, and turns to
+ * false when we are disconnected from the server.
+ */
+bool flib_netbase_connected(flib_netbase *net);
+
+/**
+ * Receive a new message and return it as a flib_netmsg. The netmsg has to be
+ * destroyed with flib_netmsg_destroy after use.
+ * Returns NULL if no message is available.
+ *
+ * Note: When a connection is closed, you probably want to call this function until
+ * no further message is returned, to ensure you see all messages that were sent
+ * before the connection closed.
+ */
+flib_netmsg *flib_netbase_recv_message(flib_netbase *net);
+
+int flib_netbase_send_raw(flib_netbase *net, const void *data, size_t len);
+
+/**
+ * Write a single message to the server. This call blocks until the
+ * message is completely written or the connection is closed or an error occurs.
+ *
+ * Returns a negative value on failure.
+ */
+int flib_netbase_send_message(flib_netbase *net, const flib_netmsg *msg);
+
+/**
+ * Send a message printf-style.
+ *
+ * flib_netbase_sendf(net, "%s\n\n", "TOGGLE_READY");
+ * flib_netbase_sendf(net, "%s\n%s\n%i\n\n", "CFG", "MAPGEN", MAPGEN_MAZE);
+ */
+int flib_netbase_sendf(flib_netbase *net, const char *format, ...);
+
+flib_netmsg *flib_netmsg_create();
+void flib_netmsg_destroy(flib_netmsg *msg);
+int flib_netmsg_append_part(flib_netmsg *msg, const void *param, size_t len);
+
+#endif /* NETBASE_H_ */
+
diff --git a/project_files/frontlib/net/netconn.c b/project_files/frontlib/net/netconn.c
new file mode 100644
index 0000000..7f45b7b
--- /dev/null
+++ b/project_files/frontlib/net/netconn.c
@@ -0,0 +1,613 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2006-2008 Igor Ulyanov <iulyanov at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2012 Simeon Maxein <smaxein at googlemail.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 "netconn_internal.h"
+#include "netprotocol.h"
+#include "../util/logging.h"
+#include "../util/util.h"
+#include "../md5/md5.h"
+#include "../base64/base64.h"
+#include "../model/mapcfg.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+
+flib_netconn *flib_netconn_create(const char *playerName, const char *dataDirPath, const char *host, int port) {
+	flib_netconn *result = NULL;
+	if(!log_badargs_if4(playerName==NULL, host==NULL, port<1, port>65535)) {
+		flib_netconn *newConn = flib_calloc(1, sizeof(flib_netconn));
+		if(newConn) {
+			newConn->netBase = flib_netbase_create(host, port);
+			newConn->playerName = flib_strdupnull(playerName);
+			newConn->dataDirPath = flib_strdupnull(dataDirPath);
+
+			newConn->netconnState = NETCONN_STATE_CONNECTING;
+
+			newConn->isChief = false;
+			newConn->map = flib_map_create_named("", "NoSuchMap");
+			newConn->pendingTeamlist.teamCount = 0;
+			newConn->pendingTeamlist.teams = NULL;
+			newConn->teamlist.teamCount = 0;
+			newConn->teamlist.teams = NULL;
+			newConn->scheme = NULL;
+			newConn->style = NULL;
+			newConn->weaponset = NULL;
+
+			newConn->running = false;
+			newConn->destroyRequested = false;
+			netconn_clearCallbacks(newConn);
+			if(newConn->netBase && newConn->playerName && newConn->dataDirPath && newConn->map) {
+				result = newConn;
+				newConn = NULL;
+			}
+		}
+		flib_netconn_destroy(newConn);
+	}
+	return result;
+}
+
+void flib_netconn_destroy(flib_netconn *conn) {
+	if(conn) {
+		if(conn->running) {
+			/*
+			 * The function was called from a callback, so the tick function is still running
+			 * and we delay the actual destruction. We ensure no further callbacks will be
+			 * sent to prevent surprises.
+			 */
+			netconn_clearCallbacks(conn);
+			conn->destroyRequested = true;
+		} else {
+			flib_netbase_destroy(conn->netBase);
+			free(conn->playerName);
+			free(conn->dataDirPath);
+
+			flib_map_destroy(conn->map);
+			flib_teamlist_clear(&conn->pendingTeamlist);
+			flib_teamlist_clear(&conn->teamlist);
+			flib_scheme_destroy(conn->scheme);
+			free(conn->style);
+			flib_weaponset_destroy(conn->weaponset);
+
+			free(conn);
+		}
+	}
+}
+
+bool flib_netconn_is_chief(flib_netconn *conn) {
+	if(!log_badargs_if(conn==NULL) && conn->netconnState==NETCONN_STATE_ROOM) {
+		return conn->isChief;
+	}
+	return false;
+}
+
+const char *flib_netconn_get_playername(flib_netconn *conn) {
+	if(!log_badargs_if(conn==NULL)) {
+		return conn->playerName;
+	}
+	return NULL;
+}
+
+void netconn_leaveRoom(flib_netconn *conn) {
+	conn->netconnState = NETCONN_STATE_LOBBY;
+	conn->isChief = false;
+	flib_map_destroy(conn->map);
+	conn->map = flib_map_create_named("", "NoSuchMap");
+	flib_teamlist_clear(&conn->pendingTeamlist);
+	flib_teamlist_clear(&conn->teamlist);
+	flib_scheme_destroy(conn->scheme);
+	conn->scheme = NULL;
+	free(conn->style);
+	conn->style = NULL;
+	flib_weaponset_destroy(conn->weaponset);
+	conn->weaponset = NULL;
+}
+
+void netconn_setMap(flib_netconn *conn, const flib_map *map) {
+	flib_map *copy = flib_map_copy(map);
+	if(copy) {
+		flib_map_destroy(conn->map);
+		conn->map = copy;
+	}
+}
+
+void netconn_setWeaponset(flib_netconn *conn, const flib_weaponset *weaponset) {
+	flib_weaponset *copy = flib_weaponset_copy(weaponset);
+	if(copy) {
+		flib_weaponset_destroy(conn->weaponset);
+		conn->weaponset = copy;
+	}
+}
+
+void netconn_setScript(flib_netconn *conn, const char *script) {
+	char *copy = flib_strdupnull(script);
+	if(copy) {
+		free(conn->style);
+		conn->style = copy;
+	}
+}
+
+void netconn_setScheme(flib_netconn *conn, const flib_scheme *scheme) {
+	flib_scheme *copy = flib_scheme_copy(scheme);
+	if(copy) {
+		flib_scheme_destroy(conn->scheme);
+		conn->scheme = copy;
+	}
+}
+
+flib_gamesetup *flib_netconn_create_gamesetup(flib_netconn *conn) {
+	flib_gamesetup *result = NULL;
+	if(!log_badargs_if(conn==NULL)) {
+		if(conn->teamlist.teamCount==0 || !conn->scheme || !conn->weaponset) {
+			flib_log_e("Incomplete room state");
+		} else {
+			flib_gamesetup stackSetup = {0};
+			stackSetup.gamescheme = conn->scheme;
+			stackSetup.map = conn->map;
+			stackSetup.style = conn->style;
+			stackSetup.teamlist = &conn->teamlist;
+			result = flib_gamesetup_copy(&stackSetup);
+			if(result) {
+				bool error = false;
+				for(int i=0; i<result->teamlist->teamCount; i++) {
+					if(flib_team_set_weaponset(result->teamlist->teams[i], conn->weaponset)) {
+						error = true;
+					}
+					flib_team_set_health(result->teamlist->teams[i], flib_scheme_get_setting(conn->scheme, "health", 100));
+				}
+				if(result->map->mapgen == MAPGEN_NAMED && result->map->name) {
+					flib_mapcfg mapcfg;
+					if(!flib_mapcfg_read(conn->dataDirPath, result->map->name, &mapcfg)) {
+						free(result->map->theme);
+						result->map->theme = flib_strdupnull(mapcfg.theme);
+						if(!result->map->theme) {
+							error = true;
+						}
+					} else {
+						flib_log_e("Unable to read map config for map %s", result->map->name);
+					}
+				}
+				if(error) {
+					flib_gamesetup_destroy(result);
+					result = NULL;
+				}
+			}
+		}
+	}
+	return result;
+}
+
+static void flib_netconn_wrappedtick(flib_netconn *conn) {
+	flib_netmsg *netmsg;
+	flib_netbase *net = conn->netBase;
+	bool exit = false;
+
+	while(!exit && !conn->destroyRequested && (netmsg=flib_netbase_recv_message(conn->netBase))) {
+		if(netmsg->partCount==0) {
+			flib_log_w("Empty server message");
+			continue;
+		}
+
+		if(flib_log_isActive(FLIB_LOGLEVEL_DEBUG)) {
+			char *buf = flib_join(netmsg->parts, netmsg->partCount, "|");
+			if(buf) {
+				flib_log_d("[Net In]%s", buf);
+			}
+			free(buf);
+		}
+
+		const char *cmd = netmsg->parts[0];
+
+	    if (!strcmp(cmd, "NICK") && netmsg->partCount>=2) {
+	    	if(netmsg->partCount<2) {
+	    		flib_log_w("Net: Malformed NICK message");
+	    	} else {
+	    		char *nick = flib_strdupnull(netmsg->parts[1]);
+	    		if(nick) {
+					free(conn->playerName);
+					conn->playerName = nick;
+	    		} else {
+					conn->netconnState = NETCONN_STATE_DISCONNECTED;
+					conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_INTERNAL_ERROR, "Out of memory");
+					exit = true;
+				}
+	    	}
+	    } else if (!strcmp(cmd, "PROTO")) {
+	        // The server just echoes this back apparently
+		} else if (!strcmp(cmd, "ERROR")) {
+			if (netmsg->partCount >= 2) {
+				conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_ERROR, netmsg->parts[1]);
+			} else {
+				conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_ERROR, "Unknown Error");
+			}
+		} else if(!strcmp(cmd, "WARNING")) {
+			if (netmsg->partCount >= 2) {
+				conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_WARNING, netmsg->parts[1]);
+			} else {
+				conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_WARNING, "Unknown Warning");
+			}
+	    } else if(!strcmp(cmd, "CONNECTED")) {
+			if(netmsg->partCount<3 || atol(netmsg->parts[2])<MIN_SERVER_VERSION) {
+				flib_log_w("Net: Server too old");
+				flib_netbase_sendf(net, "%s\n%s\n\n", "QUIT", "Server too old");
+				conn->netconnState = NETCONN_STATE_DISCONNECTED;
+				conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_SERVER_TOO_OLD, "Server too old");
+				exit = true;
+			} else {
+				flib_netbase_sendf(net, "%s\n%s\n\n", "NICK", conn->playerName);
+				flib_netbase_sendf(net, "%s\n%i\n\n", "PROTO", (int)PROTOCOL_VERSION);
+			}
+		} else if(!strcmp(cmd, "PING")) {
+	        if (netmsg->partCount > 1) {
+	        	flib_netbase_sendf(net, "%s\n%s\n\n", "PONG", netmsg->parts[1]);
+	        } else {
+	        	flib_netbase_sendf(net, "%s\n\n", "PONG");
+	        }
+	    } else if(!strcmp(cmd, "ROOMS")) {
+	        if(netmsg->partCount % 8 != 1) {
+	        	flib_log_w("Net: Malformed ROOMS message");
+	        } else {
+	        	int roomCount = netmsg->partCount/8;
+	        	flib_room **rooms = flib_room_array_from_netmsg(netmsg->parts+1, roomCount);
+	        	if(rooms) {
+	        		conn->onRoomlistCb(conn->onRoomlistCtx, (const flib_room**)rooms, roomCount);
+	        		for(int i=0; i<roomCount; i++) {
+	        			flib_room_destroy(rooms[i]);
+	        		}
+	        		free(rooms);
+	        	}
+	        }
+	    } else if (!strcmp(cmd, "SERVER_MESSAGE")) {
+	        if(netmsg->partCount < 2) {
+	        	flib_log_w("Net: Empty SERVERMESSAGE message");
+	        } else {
+	        	conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_SERVERMESSAGE, netmsg->parts[1]);
+	        }
+	    } else if (!strcmp(cmd, "CHAT")) {
+	        if(netmsg->partCount < 3) {
+	        	flib_log_w("Net: Empty CHAT message");
+	        } else {
+	        	conn->onChatCb(conn->onChatCtx, netmsg->parts[1], netmsg->parts[2]);
+	        }
+	    } else if (!strcmp(cmd, "INFO")) {
+	        if(netmsg->partCount < 5) {
+	        	flib_log_w("Net: Malformed INFO message");
+	        } else {
+	        	char *joined = flib_join(netmsg->parts+1, netmsg->partCount-1, "\n");
+	        	if(joined) {
+	        		conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_PLAYERINFO, joined);
+	        	}
+	        	free(joined);
+	        }
+	    } else if(!strcmp(cmd, "SERVER_VARS")) {
+	    	for(int offset=1; offset+2<netmsg->partCount; offset+=2) {
+	    		conn->onServerVarCb(conn->onServerVarCtx, netmsg->parts[offset], netmsg->parts[offset+1]);
+	    	}
+	    } else if (!strcmp(cmd, "CLIENT_FLAGS")) {
+	        if(netmsg->partCount < 3 || strlen(netmsg->parts[1]) < 2) {
+	        	flib_log_w("Net: Malformed CLIENT_FLAGS message");
+	        } else {
+				const char *flags = netmsg->parts[1];
+				bool setFlag = flags[0] == '+';
+
+				for(int j = 2; j < netmsg->partCount; ++j) {
+					bool isSelf = !strcmp(conn->playerName, netmsg->parts[j]);
+					if(isSelf && strchr(flags, 'h')) {
+						conn->isChief = setFlag;
+					}
+					conn->onClientFlagsCb(conn->onClientFlagsCtx, netmsg->parts[j], flags+1, setFlag);
+				}
+	        }
+	    } else if (!strcmp(cmd, "ADD_TEAM")) {
+	        if(netmsg->partCount != 24 || conn->netconnState!=NETCONN_STATE_ROOM) {
+	            flib_log_w("Net: Bad ADD_TEAM message");
+	        } else {
+	        	flib_team *team = flib_team_from_netmsg(netmsg->parts+1);
+	        	if(!team || flib_teamlist_insert(&conn->teamlist, team, conn->teamlist.teamCount)) {
+					flib_team_destroy(team);
+					conn->netconnState = NETCONN_STATE_DISCONNECTED;
+					conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_INTERNAL_ERROR, "Internal error");
+					exit = true;
+	        	} else {
+	        		conn->onTeamAddCb(conn->onTeamAddCtx, team);
+	        	}
+	        }
+	    } else if (!strcmp(cmd, "REMOVE_TEAM")) {
+	        if(netmsg->partCount != 2 || conn->netconnState!=NETCONN_STATE_ROOM) {
+	            flib_log_w("Net: Bad REMOVETEAM message");
+	        } else {
+	        	flib_teamlist_delete(&conn->teamlist, netmsg->parts[1]);
+	        	conn->onTeamDeleteCb(conn->onTeamDeleteCtx, netmsg->parts[1]);
+	        }
+	    } else if(!strcmp(cmd, "ROOMABANDONED")) {
+	    	netconn_leaveRoom(conn);
+	        conn->onLeaveRoomCb(conn->onLeaveRoomCtx, NETCONN_ROOMLEAVE_ABANDONED, "Room destroyed");
+	    } else if(!strcmp(cmd, "KICKED")) {
+	    	netconn_leaveRoom(conn);
+	    	conn->onLeaveRoomCb(conn->onLeaveRoomCtx, NETCONN_ROOMLEAVE_KICKED, "You got kicked");
+	    } else if(!strcmp(cmd, "JOINED")) {
+	        if(netmsg->partCount < 2) {
+	            flib_log_w("Net: Bad JOINED message");
+	        } else {
+				for(int i = 1; i < netmsg->partCount; ++i)
+				{
+					bool isMe = !strcmp(conn->playerName, netmsg->parts[i]);
+					if (isMe) {
+						conn->netconnState = NETCONN_STATE_ROOM;
+						conn->onEnterRoomCb(conn->onEnterRoomCtx, conn->isChief);
+					}
+
+					conn->onRoomJoinCb(conn->onRoomJoinCtx, netmsg->parts[i]);
+				}
+	        }
+	    } else if(!strcmp(cmd, "LOBBY:JOINED")) {
+	        if(netmsg->partCount < 2) {
+	            flib_log_w("Net: Bad JOINED message");
+	        } else {
+				for(int i = 1; i < netmsg->partCount; ++i)
+				{
+					bool isMe = !strcmp(conn->playerName, netmsg->parts[i]);
+					if (isMe && conn->netconnState == NETCONN_STATE_CONNECTING) {
+						conn->onConnectedCb(conn->onConnectedCtx);
+						conn->netconnState = NETCONN_STATE_LOBBY;
+					}
+					conn->onLobbyJoinCb(conn->onLobbyJoinCtx, netmsg->parts[i]);
+				}
+	        }
+	    } else if(!strcmp(cmd, "LEFT")) {
+	        if(netmsg->partCount < 2) {
+	            flib_log_w("Net: Bad LEFT message");
+	        } else {
+	        	conn->onRoomLeaveCb(conn->onRoomLeaveCtx, netmsg->parts[1], netmsg->partCount>2 ? netmsg->parts[2] : NULL);
+	        }
+	    } else if(!strcmp(cmd, "ROOM") && netmsg->partCount >= 2) {
+	    	const char *subcmd = netmsg->parts[1];
+	    	if(!strcmp(subcmd, "ADD") && netmsg->partCount == 10) {
+	    		flib_room *room = flib_room_from_netmsg(netmsg->parts+2);
+	    		if(room) {
+	    			conn->onRoomAddCb(conn->onRoomAddCtx, room);
+	    		}
+	    		flib_room_destroy(room);
+			} else if(!strcmp(subcmd, "UPD") && netmsg->partCount == 11) {
+				flib_room *room = flib_room_from_netmsg(netmsg->parts+3);
+				if(room) {
+	    			conn->onRoomUpdateCb(conn->onRoomUpdateCtx, netmsg->parts[2], room);
+	    		}
+				flib_room_destroy(room);
+			} else if(!strcmp(subcmd, "DEL") && netmsg->partCount == 3) {
+				conn->onRoomDeleteCb(conn->onRoomDeleteCtx, netmsg->parts[2]);
+			} else {
+				flib_log_w("Net: Unknown or malformed ROOM subcommand: %s", subcmd);
+			}
+	    } else if(!strcmp(cmd, "LOBBY:LEFT")) {
+	        if(netmsg->partCount < 2) {
+	            flib_log_w("Net: Bad LOBBY:LEFT message");
+	        } else {
+	        	conn->onLobbyLeaveCb(conn->onLobbyLeaveCtx, netmsg->parts[1], netmsg->partCount>2 ? netmsg->parts[2] : NULL);
+	        }
+	    } else if (!strcmp(cmd, "RUN_GAME")) {
+	        conn->onRunGameCb(conn->onRunGameCtx);
+	    } else if (!strcmp(cmd, "ASKPASSWORD")) {
+	    	conn->onPasswordRequestCb(conn->onPasswordRequestCtx, conn->playerName);
+	    } else if (!strcmp(cmd, "NOTICE")) {
+	        if(netmsg->partCount < 2) {
+	            flib_log_w("Net: Bad NOTICE message");
+	        } else {
+				errno = 0;
+				long n = strtol(netmsg->parts[1], NULL, 10);
+				if(errno) {
+					flib_log_w("Net: Bad NOTICE message");
+				} else if(n==0) {
+					conn->onNickTakenCb(conn->onNickTakenCtx, conn->playerName);
+				} else {
+					flib_log_w("Net: Unknown NOTICE message: %l", n);
+				}
+	        }
+	    } else if (!strcmp(cmd, "TEAM_ACCEPTED")) {
+	        if (netmsg->partCount != 2 || conn->netconnState!=NETCONN_STATE_ROOM) {
+	            flib_log_w("Net: Bad TEAM_ACCEPTED message");
+	        } else {
+	        	flib_team *team = flib_team_copy(flib_teamlist_find(&conn->pendingTeamlist, netmsg->parts[1]));
+	        	if(team) {
+	        		flib_teamlist_insert(&conn->teamlist, team, conn->teamlist.teamCount);
+	        		flib_teamlist_delete(&conn->pendingTeamlist, netmsg->parts[1]);
+	        	} else {
+	        		flib_log_e("Team accepted that was not requested: %s", netmsg->parts[1]);
+	        	}
+	        	conn->onTeamAcceptedCb(conn->onTeamAcceptedCtx, netmsg->parts[1]);
+	        }
+	    } else if (!strcmp(cmd, "CFG")) {
+	        if(netmsg->partCount < 3 || conn->netconnState!=NETCONN_STATE_ROOM) {
+	            flib_log_w("Net: Bad CFG message");
+	        } else {
+	        	const char *subcmd = netmsg->parts[1];
+				if(!strcmp(subcmd, "SCHEME") && netmsg->partCount == flib_meta.modCount + flib_meta.settingCount + 3) {
+					flib_scheme *cfg = flib_scheme_from_netmsg(netmsg->parts+2);
+					if(cfg) {
+						flib_scheme_destroy(conn->scheme);
+						conn->scheme = cfg;
+						conn->onSchemeChangedCb(conn->onSchemeChangedCtx, cfg);
+					} else {
+						flib_log_e("Error processing CFG SCHEME message");
+					}
+				} else if(!strcmp(subcmd, "FULLMAPCONFIG") && netmsg->partCount == 7) {
+					flib_map *map = flib_map_from_netmsg(netmsg->parts+2);
+					if(map) {
+						flib_map_destroy(conn->map);
+						conn->map = map;
+						conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_FULL);
+					} else {
+						flib_log_e("Error processing CFG FULLMAPCONFIG message");
+					}
+				} else if(!strcmp(subcmd, "MAP") && netmsg->partCount == 3) {
+					char *mapname = flib_strdupnull(netmsg->parts[2]);
+					if(mapname) {
+						free(conn->map->name);
+						conn->map->name = mapname;
+						conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_MAP);
+					} else {
+						flib_log_e("Error processing CFG MAP message");
+					}
+				} else if(!strcmp(subcmd, "THEME") && netmsg->partCount == 3) {
+					char *themename = flib_strdupnull(netmsg->parts[2]);
+					if(themename) {
+						free(conn->map->theme);
+						conn->map->theme = themename;
+						conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_THEME);
+					} else {
+						flib_log_e("Error processing CFG THEME message");
+					}
+				} else if(!strcmp(subcmd, "SEED") && netmsg->partCount == 3) {
+					char *seed = flib_strdupnull(netmsg->parts[2]);
+					if(seed) {
+						free(conn->map->seed);
+						conn->map->seed = seed;
+						conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_SEED);
+					} else {
+						flib_log_e("Error processing CFG SEED message");
+					}
+				} else if(!strcmp(subcmd, "TEMPLATE") && netmsg->partCount == 3) {
+					conn->map->templateFilter = atoi(netmsg->parts[2]);
+					conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_TEMPLATE);
+				} else if(!strcmp(subcmd, "MAPGEN") && netmsg->partCount == 3) {
+					conn->map->mapgen = atoi(netmsg->parts[2]);
+					conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_MAPGEN);
+				} else if(!strcmp(subcmd, "MAZE_SIZE") && netmsg->partCount == 3) {
+					conn->map->mazeSize = atoi(netmsg->parts[2]);
+					conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_MAZE_SIZE);
+				} else if(!strcmp(subcmd, "DRAWNMAP") && netmsg->partCount == 3) {
+					size_t drawnMapSize = 0;
+					uint8_t *drawnMapData = NULL;
+					if(!flib_drawnmapdata_from_netmsg(netmsg->parts[2], &drawnMapData, &drawnMapSize)) {
+						free(conn->map->drawData);
+						conn->map->drawData = drawnMapData;
+						conn->map->drawDataSize = drawnMapSize;
+						conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_DRAWNMAP);
+					} else {
+						flib_log_e("Error processing CFG DRAWNMAP message");
+					}
+				} else if(!strcmp(subcmd, "SCRIPT") && netmsg->partCount == 3) {
+					netconn_setScript(conn, netmsg->parts[2]);
+					conn->onScriptChangedCb(conn->onScriptChangedCtx, netmsg->parts[2]);
+				} else if(!strcmp(subcmd, "AMMO") && netmsg->partCount == 4) {
+					flib_weaponset *weapons = flib_weaponset_from_ammostring(netmsg->parts[2], netmsg->parts[3]);
+					if(weapons) {
+						flib_weaponset_destroy(conn->weaponset);
+						conn->weaponset = weapons;
+						conn->onWeaponsetChangedCb(conn->onWeaponsetChangedCtx, weapons);
+					} else {
+						flib_log_e("Error processing CFG AMMO message");
+					}
+				} else {
+					flib_log_w("Net: Unknown or malformed CFG subcommand: %s", subcmd);
+				}
+	        }
+	    } else if (!strcmp(cmd, "HH_NUM")) {
+	        if (netmsg->partCount != 3 || conn->netconnState!=NETCONN_STATE_ROOM) {
+	            flib_log_w("Net: Bad HH_NUM message");
+	        } else {
+	        	int hogs = atoi(netmsg->parts[2]);
+	        	if(hogs<=0 || hogs>HEDGEHOGS_PER_TEAM) {
+	        		flib_log_w("Net: Bad HH_NUM message: %s hogs", netmsg->parts[2]);
+	        	} else {
+	        		flib_team *team = flib_teamlist_find(&conn->teamlist, netmsg->parts[1]);
+	        		if(team) {
+	        			team->hogsInGame = hogs;
+	        		} else {
+	        			flib_log_e("HH_NUM message for unknown team %s", netmsg->parts[1]);
+	        		}
+	        		conn->onHogCountChangedCb(conn->onHogCountChangedCtx, netmsg->parts[1], hogs);
+	        	}
+	        }
+	    } else if (!strcmp(cmd, "TEAM_COLOR")) {
+	        if (netmsg->partCount != 3 || conn->netconnState!=NETCONN_STATE_ROOM) {
+	            flib_log_w("Net: Bad TEAM_COLOR message");
+	        } else {
+	        	long color;
+	        	if(sscanf(netmsg->parts[2], "%lu", &color) && color>=0 && color<flib_teamcolor_count) {
+	        		flib_team *team = flib_teamlist_find(&conn->teamlist, netmsg->parts[1]);
+	        		if(team) {
+	        			team->colorIndex = color;
+	        		} else {
+	        			flib_log_e("TEAM_COLOR message for unknown team %s", netmsg->parts[1]);
+	        		}
+	        		conn->onTeamColorChangedCb(conn->onTeamColorChangedCtx, netmsg->parts[1], color);
+	        	} else {
+	        		flib_log_w("Net: Bad TEAM_COLOR message: Color %s", netmsg->parts[2]);
+	        	}
+	        }
+	    } else if (!strcmp(cmd, "EM")) {
+	        if(netmsg->partCount < 2) {
+	            flib_log_w("Net: Bad EM message");
+	        } else {
+	        	for(int i = 1; i < netmsg->partCount; ++i) {
+					char *out = NULL;
+					size_t outlen;
+					bool ok = base64_decode_alloc(netmsg->parts[i], strlen(netmsg->parts[i]), &out, &outlen);
+					if(ok && outlen) {
+						conn->onEngineMessageCb(conn->onEngineMessageCtx, (uint8_t*)out, outlen);
+					} else {
+						flib_log_e("Net: Malformed engine message: %s", netmsg->parts[i]);
+					}
+					free(out);
+	        	}
+	        }
+	    } else if (!strcmp(cmd, "BYE")) {
+	        if (netmsg->partCount < 2) {
+	            flib_log_w("Net: Bad BYE message");
+	        } else {
+				conn->netconnState = NETCONN_STATE_DISCONNECTED;
+				if (!strcmp(netmsg->parts[1], "Authentication failed")) {
+					conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_AUTH_FAILED, netmsg->parts[1]);
+				} else {
+					conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_NORMAL, netmsg->parts[1]);
+				}
+				exit = true;
+	        }
+	    } else if (!strcmp(cmd, "ADMIN_ACCESS")) {
+	    	// deprecated
+	    } else if (!strcmp(cmd, "ROOM_CONTROL_ACCESS")) {
+	    	// deprecated
+	    } else {
+	    	flib_log_w("Unknown server command: %s", cmd);
+	    }
+		flib_netmsg_destroy(netmsg);
+	}
+
+	if(!exit && !conn->destroyRequested && !flib_netbase_connected(net)) {
+		conn->netconnState = NETCONN_STATE_DISCONNECTED;
+		conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_CONNLOST, "Connection lost");
+	}
+}
+
+void flib_netconn_tick(flib_netconn *conn) {
+	if(!log_badargs_if(conn==NULL)
+			&& !log_w_if(conn->running, "Call to flib_netconn_tick from a callback")
+			&& !log_w_if(conn->netconnState == NETCONN_STATE_DISCONNECTED, "We are already done.")) {
+		conn->running = true;
+		flib_netconn_wrappedtick(conn);
+		conn->running = false;
+
+		if(conn->destroyRequested) {
+			flib_netconn_destroy(conn);
+		}
+	}
+}
diff --git a/project_files/frontlib/net/netconn.h b/project_files/frontlib/net/netconn.h
new file mode 100644
index 0000000..3c6bbc8
--- /dev/null
+++ b/project_files/frontlib/net/netconn.h
@@ -0,0 +1,654 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/**
+ * This file contains functions for communicating with a Hedgewars server to chat, prepare and play
+ * rounds of Hedgewars.
+ *
+ * To use this, first create a netconn object by calling flib_netconn_create. This will start the
+ * connection to the game server (which might fail right away, the function returns null then). You
+ * should also register your callback functions right at the start to ensure you don't miss any
+ * callbacks.
+ *
+ * In order to allow the netconn to run, you should regularly call flib_netconn_tick(), which
+ * performs network I/O and calls your callbacks on interesting events.
+ *
+ * When the connection is closed, you will receive the onDisconnect callback. This is the signal to
+ * destroy the netconn and stop calling tick().
+ *
+ * The connection process lasts from the time you create the netconn until you receive the
+ * onConnected callback (or onDisconnected in case something goes wrong). During that time, you
+ * might receive the onNickTaken and onPasswordRequest callbacks; see their description for more
+ * information on how to handle them. You could also receive other callbacks during connecting (e.g.
+ * about the room list), but it should be safe to ignore them.
+ *
+ * Once you are connected, you are in the lobby, and you can enter rooms and leave them again. The
+ * room and lobby states have different protocols, so many commands only work in either one or the
+ * other. If you are in a room you might also be in a game, but most of the functions behave the
+ * same ingame as in a room.
+ *
+ * The state changes from lobby to room when the server tells you that you just entered one, which
+ * will also trigger the onEnterRoom callback. This usually happens in reply to either a joinRoom,
+ * createRoom or playerFollow command.
+ *
+ * The state changes back to lobby when the room is dissolved, when you are kicked from the room, or
+ * when you actively leave the room using flib_netconn_send_leaveRoom. The first two events will
+ * trigger the onLeaveRoom callback.
+ */
+
+#ifndef NETCONN_H_
+#define NETCONN_H_
+
+#include "../model/gamesetup.h"
+#include "../model/scheme.h"
+#include "../model/room.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#define NETCONN_STATE_CONNECTING 0
+#define NETCONN_STATE_LOBBY 1
+#define NETCONN_STATE_ROOM 2
+#define NETCONN_STATE_DISCONNECTED 10
+
+#define NETCONN_DISCONNECT_NORMAL 0				//!< The connection was closed normally
+#define NETCONN_DISCONNECT_SERVER_TOO_OLD 1		//!< The server has a lower protocol version than we do
+#define NETCONN_DISCONNECT_AUTH_FAILED 2		//!< You sent a password with flib_netconn_send_password that was not accepted
+#define NETCONN_DISCONNECT_CONNLOST 3			//!< The network connection was lost
+#define NETCONN_DISCONNECT_INTERNAL_ERROR 100	//!< Something went wrong in frontlib itself
+
+#define NETCONN_ROOMLEAVE_ABANDONED 0			//!< The room was closed because the chief left
+#define NETCONN_ROOMLEAVE_KICKED 1				//!< You have been kicked from the room
+
+#define NETCONN_MSG_TYPE_PLAYERINFO 0			//!< A response to flib_netconn_send_playerInfo
+#define NETCONN_MSG_TYPE_SERVERMESSAGE 1		//!< The welcome message when connecting to the lobby
+#define NETCONN_MSG_TYPE_WARNING 2				//!< A general warning message
+#define NETCONN_MSG_TYPE_ERROR 3				//!< A general error message
+
+#define NETCONN_MAPCHANGE_FULL 0
+#define NETCONN_MAPCHANGE_MAP 1
+#define NETCONN_MAPCHANGE_MAPGEN 2
+#define NETCONN_MAPCHANGE_DRAWNMAP 3
+#define NETCONN_MAPCHANGE_MAZE_SIZE 4
+#define NETCONN_MAPCHANGE_TEMPLATE 5
+#define NETCONN_MAPCHANGE_THEME 6
+#define NETCONN_MAPCHANGE_SEED 7
+
+typedef struct _flib_netconn flib_netconn;
+
+/**
+ * Create a new netplay connection with these parameters.
+ * The path to the data directory must end with a path delimiter (e.g. C:\Games\Hedgewars\Data\)
+ */
+flib_netconn *flib_netconn_create(const char *playerName, const char *dataDirPath, const char *host, int port);
+void flib_netconn_destroy(flib_netconn *conn);
+
+/**
+ * Perform I/O operations and call callbacks if something interesting happens.
+ * Should be called regularly.
+ */
+void flib_netconn_tick(flib_netconn *conn);
+
+/**
+ * Are you currently the owner of this room? The return value only makes sense in
+ * NETCONN_STATE_ROOM and NETCONN_STATE_INGAME states.
+ */
+bool flib_netconn_is_chief(flib_netconn *conn);
+
+/**
+ * Returns the playername. This is *probably* the one provided on creation, but if that name was
+ * already taken, a different one could have been set by the onNickTaken callback or its default
+ * implementation.
+ */
+const char *flib_netconn_get_playername(flib_netconn *conn);
+
+/**
+ * Generate a game setup from the current room state.
+ * Returns NULL if the room state does not contain enough information for a complete game setup,
+ * or if an error occurs.
+ *
+ * The new gamesetup must be destroyed with flib_gamesetup_destroy().
+ */
+flib_gamesetup *flib_netconn_create_gamesetup(flib_netconn *conn);
+
+
+
+
+// Send functions needed when connecting and disconnecting
+
+	/**
+	 * Request a different nickname.
+	 * This function only makes sense in reaction to an onNickTaken callback, because the netconn
+	 * automatically requests the nickname you provide on creation, and once the server accepts the
+	 * nickname it can no longer be changed.
+	 */
+	int flib_netconn_send_nick(flib_netconn *conn, const char *nick);
+
+	/**
+	 * Send the password in reply to a password request.
+	 * If the server does not accept the password, you will be disconnected
+	 * (NETCONN_DISCONNECT_AUTH_FAILED)
+	 */
+	int flib_netconn_send_password(flib_netconn *conn, const char *passwd);
+
+	/**
+	 * Tell the server that you want to leave. If successful, the server will disconnect you.
+	 */
+	int flib_netconn_send_quit(flib_netconn *conn, const char *quitmsg);
+
+
+// Send functions that make sense both in the lobby and in rooms
+
+	/**
+	 * Send a chat message. This message is either sent to the lobby or the room, depending on
+	 * whether you are in a room at the moment. The message is not echoed back to you.
+	 */
+	int flib_netconn_send_chat(flib_netconn *conn, const char *chat);
+
+	/**
+	 * Kick a player. This has different meanings in the lobby and in a room;
+	 * In the lobby, it will kick the player from the server, and you need to be a server admin to
+	 * do it. In a room, it will kick the player from the room, and you need to be room chief.
+	 */
+	int flib_netconn_send_kick(flib_netconn *conn, const char *playerName);
+
+	/**
+	 * Request information about a player (e.g. current room, version, partial IP). If the action
+	 * succeeds, you will receive an onMessage callback with NETCONN_MSG_TYPE_PLAYERINFO containing
+	 * the requested information.
+	 */
+	int flib_netconn_send_playerInfo(flib_netconn *conn, const char *playerName);
+
+
+// Send functions that only make sense in the lobby
+
+	/**
+	 * Request an update of the room list. Only makes sense when in lobby state.
+	 * If the action succeeds, you will receive an onRoomlist callback containing the current room
+	 * data.
+	 */
+	int flib_netconn_send_request_roomlist(flib_netconn *conn);
+
+	/**
+	 * Join a room as guest (not chief). Only makes sense when in lobby state. If the action
+	 * succeeds, you will receive an onEnterRoom callback with chief=false followed by other
+	 * callbacks with current room information.
+	 */
+	int flib_netconn_send_joinRoom(flib_netconn *conn, const char *room);
+
+	/**
+	 * Follow a player. Only valid in the lobby. If the player is in a room (or in a game), this
+	 * command is analogous to calling flib_netconn_send_joinRoom with that room.
+	 */
+	int flib_netconn_send_playerFollow(flib_netconn *conn, const char *playerName);
+
+	/**
+	 * Create and join a new room. Only makes sense when in lobby state. If the action succeeds,
+	 * you will receive an onEnterRoom callback with chief=true.
+	 */
+	int flib_netconn_send_createRoom(flib_netconn *conn, const char *room);
+
+	/**
+	 * Ban a player. The scope of this ban depends on whether you are in a room or in the lobby.
+	 * In a room, you need to be the room chief, and the ban will apply to the room only. In the
+	 * lobby, you need to be server admin to ban someone, and the ban applies to the entire server.
+	 */
+	int flib_netconn_send_ban(flib_netconn *conn, const char *playerName);
+
+	/**
+	 * Does something administrator-y. At any rate you need to be an administrator and in the lobby
+	 * to use this command.
+	 */
+	int flib_netconn_send_clearAccountsCache(flib_netconn *conn);
+
+	/**
+	 * Sets a server variable to the indicated value. Only makes sense if you are server admin and
+	 * in the lobby. Known variables are MOTD_NEW, MOTD_OLD and LATEST_PROTO. MOTD_OLD is shown to
+	 * players with older protocol versions, to inform them that they might want to update.
+	 */
+	int flib_netconn_send_setServerVar(flib_netconn *conn, const char *name, const char *value);
+
+	/**
+	 * Queries all server variables. Only makes sense if you are server admin and in the lobby.
+	 * If the action succeeds, you will receive several onServerVar callbacks with the
+	 * current values of all server variables.
+	 */
+	int flib_netconn_send_getServerVars(flib_netconn *conn);
+
+
+// Send functions that only make sense in a room
+
+	/**
+	 * Leave the room for the lobby. Only makes sense in room state. msg can be NULL if you don't
+	 * want to send a message. The server always accepts a part command, so once you send it off,
+	 * you can just assume that you are back in the lobby.
+	 */
+	int flib_netconn_send_leaveRoom(flib_netconn *conn, const char *msg);
+
+	/**
+	 * Change your "ready" status in the room. Only makes sense when in room state. If the action
+	 * succeeds, you will receive an onClientFlags callback containing the change.
+	 */
+	int flib_netconn_send_toggleReady(flib_netconn *conn);
+
+	/**
+	 * Add a team to the current room. Apart from the "fixed" team information, this also includes
+	 * the color, but not the number of hogs. Only makes sense when in room state. If the action
+	 * succeeds, you will receive an onTeamAccepted callback with the name of the team.
+	 *
+	 * Notes: Technically, sending a color here is the only way for a non-chief to set the color of
+	 * her own team. The server remembers this color and even generates a separate teamColor message
+	 * to inform everyone of it. However, at the moment the frontends generally override this color
+	 * with one they choose themselves in order to deal with unfortunate behavior of the QtFrontend,
+	 * which always sends color index 0 when adding a team but thinks that the team has a random
+	 * color. The chief always sends a new color in order to bring the QtFrontend back into sync.
+	 */
+	int flib_netconn_send_addTeam(flib_netconn *conn, const flib_team *team);
+
+	/**
+	 * Remove the team with the name teamname. Only makes sense when in room state.
+	 * The server does not send a reply on success.
+	 */
+	int flib_netconn_send_removeTeam(flib_netconn *conn, const char *teamname);
+
+
+// Send functions that only make sense in a room and if you are room chief
+
+	/**
+	 * Rename the current room. Only makes sense in room state and if you are chief. If the action
+	 * succeeds, you (and everyone else on the server) will receive an onRoomUpdate message
+	 * containing the change.
+	 */
+	int flib_netconn_send_renameRoom(flib_netconn *conn, const char *roomName);
+
+	/**
+	 * Set the number of hogs for a team. Only makes sense in room state and if you are chief.
+	 * The server does not send a reply.
+	 */
+	int flib_netconn_send_teamHogCount(flib_netconn *conn, const char *teamname, int hogcount);
+
+	/**
+	 * Set the teamcolor of a team. Only makes sense in room state and if you are chief.
+	 * The server does not send a reply.
+	 */
+	int flib_netconn_send_teamColor(flib_netconn *conn, const char *teamname, int colorIndex);
+
+	/**
+	 * Set the weaponset for the room. Only makes sense in room state and if you are chief.
+	 * The server does not send a reply.
+	 */
+	int flib_netconn_send_weaponset(flib_netconn *conn, const flib_weaponset *weaponset);
+
+	/**
+	 * Set the map for the room. Only makes sense in room state and if you are chief.
+	 * The server does not send a reply.
+	 */
+	int flib_netconn_send_map(flib_netconn *conn, const flib_map *map);
+
+	/**
+	 * Set the mapname. Only makes sense in room state and if you are chief.
+	 * The server does not send a reply.
+	 */
+	int flib_netconn_send_mapName(flib_netconn *conn, const char *mapName);
+
+	/**
+	 * Set the map generator (regular, maze, drawn, named). Only makes sense in room state and if
+	 * you are chief.
+	 * The server does not send a reply.
+	 */
+	int flib_netconn_send_mapGen(flib_netconn *conn, int mapGen);
+
+	/**
+	 * Set the map template for regular maps. Only makes sense in room state and if you are chief.
+	 * The server does not send a reply.
+	 */
+	int flib_netconn_send_mapTemplate(flib_netconn *conn, int templateFilter);
+
+	/**
+	 * Set the maze template (maze size) for mazes. Only makes sense in room state and if you are
+	 * chief. The server does not send a reply.
+	 */
+	int flib_netconn_send_mapMazeSize(flib_netconn *conn, int mazeSize);
+
+	/**
+	 * Set the seed for the map. Only makes sense in room state and if you are chief.
+	 * The server does not send a reply.
+	 */
+	int flib_netconn_send_mapSeed(flib_netconn *conn, const char *seed);
+
+	/**
+	 * Set the theme for the map. Only makes sense in room state and if you are chief.
+	 * The server does not send a reply.
+	 */
+	int flib_netconn_send_mapTheme(flib_netconn *conn, const char *theme);
+
+	/**
+	 * Set the draw data for the drawn map. Only makes sense in room state and if you are chief.
+	 * The server does not send a reply.
+	 */
+	int flib_netconn_send_mapDrawdata(flib_netconn *conn, const uint8_t *drawData, size_t size);
+
+	/**
+	 * Set the script (game style). Only makes sense in room state and if you are chief.
+	 * The server does not send a reply.
+	 */
+	int flib_netconn_send_script(flib_netconn *conn, const char *scriptName);
+
+	/**
+	 * Set the scheme. Only makes sense in room state and if you are chief.
+	 * The server does not send a reply.
+	 */
+	int flib_netconn_send_scheme(flib_netconn *conn, const flib_scheme *scheme);
+
+	/**
+	 * Signal that you want to start the game. Only makes sense in room state and if you are chief.
+	 * The server will check whether all players are ready and whether it believes the setup makes
+	 * sense (e.g. more than one clan). If the server is satisfied, you will receive an onRunGame
+	 * callback (all other clients in the room are notified the same way). Otherwise the server
+	 * might answer with a warning, or might not answer at all.
+	 */
+	int flib_netconn_send_startGame(flib_netconn *conn);
+
+	/**
+	 * Allow/forbid players to join the room. Only makes sense in room state and if you are chief.
+	 * The server does not send a reply.
+	 */
+	int flib_netconn_send_toggleRestrictJoins(flib_netconn *conn);
+
+	/**
+	 * Allow/forbid adding teams to the room. Only makes sense in room state and if you are chief.
+	 * The server does not send a reply.
+	 */
+	int flib_netconn_send_toggleRestrictTeams(flib_netconn *conn);
+
+
+// Send functions that are only needed for running a game
+
+	/**
+	 * Send a teamchat message, forwarded from the engine. Only makes sense ingame.
+	 * The server does not send a reply. In contrast to a Chat message, the server
+	 * automatically converts this into an engine message and passes it on to the other
+	 * clients.
+	 */
+	int flib_netconn_send_teamchat(flib_netconn *conn, const char *msg);
+
+	/**
+	 * Send an engine message. Only makes sense when ingame. In a networked game, you have to pass
+	 * all the engine messages from the engine here, and they will be spread to all other clients
+	 * in the game to keep the game in sync.
+	 */
+	int flib_netconn_send_engineMessage(flib_netconn *conn, const uint8_t *message, size_t size);
+
+	/**
+	 * Inform the server that the round has ended. Call this when the engine has disconnected,
+	 * passing 1 if the round ended normally, 0 otherwise.
+	 */
+	int flib_netconn_send_roundfinished(flib_netconn *conn, bool withoutError);
+
+
+
+
+
+// Callbacks that are important for connecting/disconnecting
+
+	/**
+	 * onNickTaken is called when connecting to the server, if it turns out that there is already a
+	 * player with the same nick.
+	 * In order to proceed, a new nickname needs to be sent to the server using
+	 * flib_netconn_send_nick() (or of course you can bail out and send a QUIT).
+	 * If you don't set a callback, the netconn will automatically react by generating a new name.
+	 */
+	void flib_netconn_onNickTaken(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context);
+
+	/**
+	 * When connecting with a registered nickname, the server will ask for a password before
+	 * admitting you in. This callback is called when that happens. As a reaction, you can send the
+	 * password using flib_netconn_send_password. If you don't register a callback, the default
+	 * behavior is to just quit in a way that will cause a disconnect with
+	 * NETCONN_DISCONNECT_AUTH_FAILED.
+	 *
+	 * You can't just choose a new nickname when you receive this callback, because at that point
+	 * the server has already accepted your nick.
+	 */
+	void flib_netconn_onPasswordRequest(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context);
+
+	/**
+	 * This is called when the server has accepted our nickname (and possibly password) and we have
+	 * entered the lobby.
+	 */
+	void flib_netconn_onConnected(flib_netconn *conn, void (*callback)(void *context), void* context);
+
+	/**
+	 * This is always the last callback (unless the netconn is destroyed early), and the netconn
+	 * should be destroyed when it is received. The reason for the disconnect is passed as one of
+	 * the NETCONN_DISCONNECT_ constants. Sometimes a message is included as well, but that
+	 * parameter might also be NULL.
+	 */
+	void flib_netconn_onDisconnected(flib_netconn *conn, void (*callback)(void *context, int reason, const char *message), void* context);
+
+
+// Callbacks that make sense in most situations
+
+	/**
+	 * Callback for several informational messages that should be displayed to the user
+	 * (e.g. in the chat window), but do not require a reaction. If a game is running, you might
+	 * want to redirect some of these messages to the engine as well so the user will see them.
+	 */
+	void flib_netconn_onMessage(flib_netconn *conn, void (*callback)(void *context, int msgtype, const char *msg), void* context);
+
+	/**
+	 * We received a chat message. Where this message belongs depends on the current state
+	 * (lobby/room). If a game is running the message should be passed to the engine.
+	 */
+	void flib_netconn_onChat(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *msg), void* context);
+
+	/**
+	 * Callbacks for incremental room list updates. They will fire whenever these events occur,
+	 * even before you first query the actual roomlist - so be sure not to blindly reference your
+	 * room list in these callbacks. The server currently only sends updates when a room changes
+	 * its name, so in order to update other room information you need to query the roomlist again
+	 * (see send_request_roomlist / onRoomlist).
+	 */
+	void flib_netconn_onRoomAdd(flib_netconn *conn, void (*callback)(void *context, const flib_room *room), void* context);
+	void flib_netconn_onRoomDelete(flib_netconn *conn, void (*callback)(void *context, const char *name), void* context);
+	void flib_netconn_onRoomUpdate(flib_netconn *conn, void (*callback)(void *context, const char *oldName, const flib_room *room), void* context);
+
+	/**
+	 * Callbacks for players joining or leaving the lobby. In contrast to the roomlist updates, you
+	 * will get a JOIN callback for every player already on the server when you join (and there is
+	 * no direct way to query the current playerlist)
+	 *
+	 * NOTE: partMessage may be NULL.
+	 */
+	void flib_netconn_onLobbyJoin(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context);
+	void flib_netconn_onLobbyLeave(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *partMessage), void* context);
+
+	/**
+	 * This is called when the server informs us that one or more flags associated with a
+	 * player/client have changed.
+	 *
+	 * nick is the name of the player, flags is a string containing one character for each modified
+	 * flag (see below), and newFlagState signals whether the flags should be set to true or false.
+	 *
+	 * Some of these flags are important for protocol purposes (especially if they are set for you)
+	 * while others are just informational. Also, some flags are only relevant for players who are
+	 * in the same room as you, and the server will not inform you if they change for others.
+	 *
+	 * These are the currently known/used flags:
+	 * a: Server admin. Always updated.
+	 * h: Room chief. Updated when in the same room.
+	 * r: Ready to play. Updated when in the same room.
+	 * u: Registered user. Always updated.
+	 *
+	 * The server tells us the 'a' and 'u' flags for all players when we first join the lobby, and
+	 * also tells us the 'r' and 'h' flags when we join or create a room. It assumes that all flags
+	 * are initially false, so it will typically only tell you to set certain flags to true when
+	 * transmitting the initial states. Reset the 'h' and 'r' flags to false when leaving a room,
+	 * or when entering room state, to arrive at the right state for each player.
+	 *
+	 * The room chief state of yourself is particularly important because it determines whether you
+	 * can modify settings of the current room. Generally, when you create a room you start out
+	 * being room chief, and when you join an existing room you are not. However, if the original
+	 * chief leaves a room, the server can choose a new chief, and if that happens the chief flag
+	 * will be transferred to someone else.
+	 */
+	void flib_netconn_onClientFlags(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *flags, bool newFlagState), void *context);
+
+// Callbacks that happen only in response to specific requests
+
+	/**
+	 * Response to flib_netconn_send_request_roomlist().
+	 * The rooms array contains the current state of all rooms on the server.
+	 */
+	void flib_netconn_onRoomlist(flib_netconn *conn, void (*callback)(void *context, const flib_room **rooms, int roomCount), void* context);
+
+	/**
+	 * Response to flib_netconn_send_joinRoom, flib_netconn_send_playerFollow or
+	 * flib_netconn_send_createRoom.
+	 *
+	 * You just left the lobby and entered a room.
+	 * If chief is true, you can and should send a full configuration for the room now. This
+	 * consists of ammo, scheme, script and map, where map apparently has to come last.
+	 */
+	void flib_netconn_onEnterRoom(flib_netconn *conn, void (*callback)(void *context, bool chief), void *context);
+
+	/**
+	 * Response to flib_netconn_send_addTeam.
+	 * The server might reject your team for several reasons, e.g. because it has the same name as
+	 * an existing team, or because the room chief restricted adding new teams. If the team is
+	 * accepted by the server, this callback is fired.
+	 *
+	 * If you are the room chief, you are expected to provide the hog count for your own team now
+	 * using flib_netconn_send_teamHogCount. The color of the team is already set to the one you
+	 * provided in addTeam.
+	 */
+	void flib_netconn_onTeamAccepted(flib_netconn *conn, void (*callback)(void *context, const char *team), void *context);
+
+	/**
+	 * When you query the server vars with flib_netconn_send_getServerVars (only works as admin),
+	 * the server replies with a list of them. This callback is called for each entry in that list.
+	 */
+	void flib_netconn_onServerVar(flib_netconn *conn, void (*callback)(void *context, const char *name, const char *value), void *context);
+
+
+// Callbacks that are only relevant in a room
+
+	/**
+	 * You just left a room and entered the lobby again.
+	 * reason is one of the NETCONN_ROOMLEAVE_ constants (usually a kick).
+	 * This will not be called when you actively leave a room using PART.
+	 * Don't confuse with onRoomLeave, which indicates that *someone else* left the room.
+	 */
+	void flib_netconn_onLeaveRoom(flib_netconn *conn, void (*callback)(void *context, int reason, const char *message), void *context);
+
+	/**
+	 * Someone joined or left the room you are currently in.
+	 * Analogous to onLobbyJoin/leave, you will receive the join callback for all players that are
+	 * already in the room when you join, including for yourself (this is actually how it is
+	 * determined that you joined a room).
+	 *
+	 * However, you will *not* receive onRoomLeave messages for everyone when you leave the room.
+	 */
+	void flib_netconn_onRoomJoin(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context);
+	void flib_netconn_onRoomLeave(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *partMessage), void* context);
+
+	/**
+	 * A new team was added to the room. The person who adds a team does NOT receive this callback
+	 * (he gets onTeamAccepted instead).
+	 *
+	 * The team does not contain bindings, stats, weaponset, color or the number of hogs (but it is
+	 * assumed to be the default of 4).
+	 *
+	 * If you receive this message and you are the room chief, you may want to send a color and hog
+	 * count for this team using flib_netconn_send_teamHogCount / teamColor for QtFrontend
+	 * compatibility.
+	 *
+	 * The server currently sends another message with the color of the team to the same recipients
+	 * as this teamAdd message, which will trigger an onTeamColorChanged callback. See the
+	 * description of flib_netconn_send_addTeam for more information.
+	 */
+	void flib_netconn_onTeamAdd(flib_netconn *conn, void (*callback)(void *context, const flib_team *team), void *context);
+
+	/**
+	 * A team was removed from the room. The person who removed the team will not receive this
+	 * callback.
+	 */
+	void flib_netconn_onTeamDelete(flib_netconn *conn, void (*callback)(void *context, const char *teamname), void *context);
+
+	/**
+	 * The number of hogs in a team has been changed by the room chief. If you are the chief and
+	 * change the number of hogs yourself, you will not receive this callback.
+	 */
+	void flib_netconn_onHogCountChanged(flib_netconn *conn, void (*callback)(void *context, const char *teamName, int hogs), void *context);
+
+	/**
+	 * The color of a team has been set or changed. The client who set or changed the color will
+	 * not receive this callback.
+	 *
+	 * Normally, only the chief can change the color of a team. However, this message is also
+	 * generated when a team is added, so you can receive it even as chief.
+	 */
+	void flib_netconn_onTeamColorChanged(flib_netconn *conn, void (*callback)(void *context, const char *teamName, int colorIndex), void *context);
+
+	/**
+	 * The room chief has changed the game scheme (or you just joined a room).
+	 * You will not receive this callback if you changed the scheme yourself.
+	 */
+	void flib_netconn_onSchemeChanged(flib_netconn *conn, void (*callback)(void *context, const flib_scheme *scheme), void *context);
+
+	/**
+	 * The room chief has changed the map (or you just joined a room). Only non-chiefs receive these
+	 * messages.
+	 *
+	 * To reduce the number of callback functions, the netconn keeps track of the current map
+	 * settings and always passes the entire current map config, but informs the callee about what
+	 * has changed (see the NETCONN_MAPCHANGE_ constants).
+	 *
+	 * Caution: Due to the way the protocol works, the map might not be complete at this point if it
+	 * is a hand-drawn map, because the "full" map config does not include the drawn map data.
+	 */
+	void flib_netconn_onMapChanged(flib_netconn *conn, void (*callback)(void *context, const flib_map *map, int changetype), void *context);
+
+	/**
+	 * The room chief has changed the game style (or you just joined a room). If you are the chief
+	 * and change the style yourself, you will not receive this callback.
+	 */
+	void flib_netconn_onScriptChanged(flib_netconn *conn, void (*callback)(void *context, const char *script), void *context);
+
+	/**
+	 * The room chief has changed the weaponset (or you just joined a room). If you are the chief
+	 * and change the weaponset yourself, you will not receive this callback.
+	 */
+	void flib_netconn_onWeaponsetChanged(flib_netconn *conn, void (*callback)(void *context, const flib_weaponset *weaponset), void *context);
+
+	/**
+	 * The game is starting. Fire up the engine and join in!
+	 * You can let the netconn generate the right game setup using flib_netconn_create_gamesetup
+	 */
+	void flib_netconn_onRunGame(flib_netconn *conn, void (*callback)(void *context), void *context);
+
+	/**
+	 * You are in a room, a game is in progress, and the server is sending you the new input for the
+	 * engine to keep up to date with the current happenings. Pass it on to the engine using
+	 * flib_gameconn_send_enginemsg.
+	 */
+	void flib_netconn_onEngineMessage(flib_netconn *conn, void (*callback)(void *context, const uint8_t *message, size_t size), void *context);
+
+#endif
diff --git a/project_files/frontlib/net/netconn_callbacks.c b/project_files/frontlib/net/netconn_callbacks.c
new file mode 100644
index 0000000..8b59539
--- /dev/null
+++ b/project_files/frontlib/net/netconn_callbacks.c
@@ -0,0 +1,149 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "netconn_internal.h"
+
+#include "../util/logging.h"
+#include "../util/util.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+static void defaultCallback_onMessage(void *context, int msgtype, const char *msg) {
+	flib_log_i("Net: [%i] %s", msgtype, msg);
+}
+
+static void defaultCallback_onChat(void *context, const char *nick, const char *msg) {
+	flib_log_i("%s: %s", nick, msg);
+}
+
+// Change the name by suffixing it with a number. If it already ends in a number, increase that number by 1.
+static void defaultCallback_onNickTaken(void *context, const char *requestedNick) {
+	flib_netconn *conn = context;
+	size_t namelen = strlen(requestedNick);
+	int digits = 0;
+	while(digits<namelen && isdigit(requestedNick[namelen-1-digits])) {
+		digits++;
+	}
+	long suffix = 0;
+	if(digits>0) {
+		suffix = atol(requestedNick+namelen-digits)+1;
+	}
+	char *newPlayerName = flib_asprintf("%.*s%li", namelen-digits, requestedNick, suffix);
+	if(newPlayerName) {
+		flib_netconn_send_nick(conn, newPlayerName);
+	} else {
+		flib_netconn_send_quit(conn, "Nick already taken.");
+	}
+	free(newPlayerName);
+}
+
+// Default behavior: Quit
+static void defaultCallback_onPasswordRequest(void *context, const char *requestedNick) {
+	flib_netconn_send_quit((flib_netconn*)context, "Authentication failed");
+}
+
+void netconn_clearCallbacks(flib_netconn *conn) {
+	flib_netconn_onMessage(conn, NULL, NULL);
+	flib_netconn_onConnected(conn, NULL, NULL);
+	flib_netconn_onDisconnected(conn, NULL, NULL);
+	flib_netconn_onRoomlist(conn, NULL, NULL);
+	flib_netconn_onRoomAdd(conn, NULL, NULL);
+	flib_netconn_onRoomDelete(conn, NULL, NULL);
+	flib_netconn_onRoomUpdate(conn, NULL, NULL);
+	flib_netconn_onClientFlags(conn, NULL, NULL);
+	flib_netconn_onChat(conn, NULL, NULL);
+	flib_netconn_onLobbyJoin(conn, NULL, NULL);
+	flib_netconn_onLobbyLeave(conn, NULL, NULL);
+	flib_netconn_onRoomJoin(conn, NULL, NULL);
+	flib_netconn_onRoomLeave(conn, NULL, NULL);
+	flib_netconn_onNickTaken(conn, NULL, NULL);
+	flib_netconn_onPasswordRequest(conn, NULL, NULL);
+	flib_netconn_onEnterRoom(conn, NULL, NULL);
+	flib_netconn_onLeaveRoom(conn, NULL, NULL);
+	flib_netconn_onTeamAdd(conn, NULL, NULL);
+	flib_netconn_onTeamDelete(conn, NULL, NULL);
+	flib_netconn_onRunGame(conn, NULL, NULL);
+	flib_netconn_onTeamAccepted(conn, NULL, NULL);
+	flib_netconn_onHogCountChanged(conn, NULL, NULL);
+	flib_netconn_onTeamColorChanged(conn, NULL, NULL);
+	flib_netconn_onEngineMessage(conn, NULL, NULL);
+	flib_netconn_onSchemeChanged(conn, NULL, NULL);
+	flib_netconn_onMapChanged(conn, NULL, NULL);
+	flib_netconn_onScriptChanged(conn, NULL, NULL);
+	flib_netconn_onWeaponsetChanged(conn, NULL, NULL);
+	flib_netconn_onServerVar(conn, NULL, NULL);
+}
+
+/**
+ * This macro generates a callback setter function. It uses the name of the callback to
+ * automatically generate the function name and the fields to set, so a consistent naming
+ * convention needs to be enforced (not that that is a bad thing). If null is passed as
+ * callback to the generated function, the defaultCb will be set instead (with conn
+ * as the context).
+ */
+#define GENERATE_CB_SETTER(cbName, cbParameterTypes, defaultCb) \
+	void flib_netconn_##cbName(flib_netconn *conn, void (*callback)cbParameterTypes, void *context) { \
+		if(!log_badargs_if(conn==NULL)) { \
+			conn->cbName##Cb = callback ? callback : &defaultCb; \
+			conn->cbName##Ctx = callback ? context : conn; \
+		} \
+	}
+
+/**
+ * Generate a callback setter function like GENERATE_CB_SETTER, and automatically generate a
+ * no-op callback function as well that is used as default.
+ */
+#define GENERATE_CB_SETTER_AND_DEFAULT(cbName, cbParameterTypes) \
+	static void _noop_callback_##cbName cbParameterTypes {} \
+	GENERATE_CB_SETTER(cbName, cbParameterTypes, _noop_callback_##cbName)
+
+GENERATE_CB_SETTER(onMessage, (void *context, int msgtype, const char *msg), defaultCallback_onMessage);
+GENERATE_CB_SETTER_AND_DEFAULT(onConnected, (void *context));
+GENERATE_CB_SETTER_AND_DEFAULT(onDisconnected, (void *context, int reason, const char *message));
+GENERATE_CB_SETTER_AND_DEFAULT(onRoomlist, (void *context, const flib_room **rooms, int roomCount));
+GENERATE_CB_SETTER_AND_DEFAULT(onRoomAdd, (void *context, const flib_room *room));
+GENERATE_CB_SETTER_AND_DEFAULT(onRoomDelete, (void *context, const char *name));
+GENERATE_CB_SETTER_AND_DEFAULT(onRoomUpdate, (void *context, const char *oldName, const flib_room *room));
+GENERATE_CB_SETTER_AND_DEFAULT(onClientFlags, (void *context, const char *nick, const char *flags, bool newFlagState));
+GENERATE_CB_SETTER(onChat, (void *context, const char *nick, const char *msg), defaultCallback_onChat);
+GENERATE_CB_SETTER_AND_DEFAULT(onLobbyJoin, (void *context, const char *nick));
+GENERATE_CB_SETTER_AND_DEFAULT(onLobbyLeave, (void *context, const char *nick, const char *partMsg));
+GENERATE_CB_SETTER_AND_DEFAULT(onRoomJoin, (void *context, const char *nick));
+GENERATE_CB_SETTER_AND_DEFAULT(onRoomLeave, (void *context, const char *nick, const char *partMessage));
+GENERATE_CB_SETTER(onNickTaken, (void *context, const char *nick), defaultCallback_onNickTaken);
+GENERATE_CB_SETTER(onPasswordRequest, (void *context, const char *nick), defaultCallback_onPasswordRequest);
+GENERATE_CB_SETTER_AND_DEFAULT(onEnterRoom, (void *context, bool chief));
+GENERATE_CB_SETTER_AND_DEFAULT(onLeaveRoom, (void *context, int reason, const char *message));
+GENERATE_CB_SETTER_AND_DEFAULT(onTeamAdd, (void *context, const flib_team *team));
+GENERATE_CB_SETTER_AND_DEFAULT(onTeamDelete, (void *context, const char *teamname));
+GENERATE_CB_SETTER_AND_DEFAULT(onRunGame, (void *context));
+GENERATE_CB_SETTER_AND_DEFAULT(onTeamAccepted, (void *context, const char *teamName));
+GENERATE_CB_SETTER_AND_DEFAULT(onHogCountChanged, (void *context, const char *teamName, int hogs));
+GENERATE_CB_SETTER_AND_DEFAULT(onTeamColorChanged, (void *context, const char *teamName, int colorIndex));
+GENERATE_CB_SETTER_AND_DEFAULT(onEngineMessage, (void *context, const uint8_t *message, size_t size));
+GENERATE_CB_SETTER_AND_DEFAULT(onSchemeChanged, (void *context, const flib_scheme *scheme));
+GENERATE_CB_SETTER_AND_DEFAULT(onMapChanged, (void *context, const flib_map *map, int changetype));
+GENERATE_CB_SETTER_AND_DEFAULT(onScriptChanged, (void *context, const char *script));
+GENERATE_CB_SETTER_AND_DEFAULT(onWeaponsetChanged, (void *context, const flib_weaponset *weaponset));
+GENERATE_CB_SETTER_AND_DEFAULT(onServerVar, (void *context, const char *name, const char *value));
+
+#undef GENERATE_CB_SETTER_AND_DEFAULT
+#undef GENERATE_CB_SETTER
diff --git a/project_files/frontlib/net/netconn_internal.h b/project_files/frontlib/net/netconn_internal.h
new file mode 100644
index 0000000..72a352c
--- /dev/null
+++ b/project_files/frontlib/net/netconn_internal.h
@@ -0,0 +1,151 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/**
+ * Common definitions needed by netconn functions, to allow splitting them into several files.
+ */
+
+#ifndef NETCONN_INTERNAL_H_
+#define NETCONN_INTERNAL_H_
+
+#include "netconn.h"
+#include "netbase.h"
+#include "../model/map.h"
+#include "../model/team.h"
+#include "../model/weapon.h"
+#include "../model/room.h"
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stddef.h>
+
+struct _flib_netconn {
+	flib_netbase *netBase;
+	char *playerName;
+	char *dataDirPath;
+
+	int netconnState;			//!< One of the NETCONN_STATE constants
+
+	bool isChief;				//!< Player can modify the current room
+	flib_map *map;
+	flib_teamlist pendingTeamlist;
+	flib_teamlist teamlist;
+	flib_scheme *scheme;
+	char *style;
+	flib_weaponset *weaponset;
+
+	void (*onMessageCb)(void *context, int msgtype, const char *msg);
+	void *onMessageCtx;
+
+	void (*onConnectedCb)(void *context);
+	void *onConnectedCtx;
+
+	void (*onDisconnectedCb)(void *context, int reason, const char *message);
+	void *onDisconnectedCtx;
+
+	void (*onRoomlistCb)(void *context, const flib_room **rooms, int roomCount);
+	void *onRoomlistCtx;
+
+	void (*onRoomAddCb)(void *context, const flib_room *room);
+	void *onRoomAddCtx;
+
+	void (*onRoomDeleteCb)(void *context, const char *name);
+	void *onRoomDeleteCtx;
+
+	void (*onRoomUpdateCb)(void *context, const char *oldName, const flib_room *room);
+	void *onRoomUpdateCtx;
+
+	void (*onClientFlagsCb)(void *context, const char *nick, const char *flags, bool newFlagState);
+	void *onClientFlagsCtx;
+
+	void (*onChatCb)(void *context, const char *nick, const char *msg);
+	void *onChatCtx;
+
+	void (*onLobbyJoinCb)(void *context, const char *nick);
+	void *onLobbyJoinCtx;
+
+	void (*onLobbyLeaveCb)(void *context, const char *nick, const char *partMessage);
+	void *onLobbyLeaveCtx;
+
+	void (*onRoomJoinCb)(void *context, const char *nick);
+	void *onRoomJoinCtx;
+
+	void (*onRoomLeaveCb)(void *context, const char *nick, const char *partMessage);
+	void *onRoomLeaveCtx;
+
+	void (*onNickTakenCb)(void *context, const char *nick);
+	void *onNickTakenCtx;
+
+	void (*onPasswordRequestCb)(void *context, const char *nick);
+	void *onPasswordRequestCtx;
+
+	void (*onEnterRoomCb)(void *context, bool chief);
+	void *onEnterRoomCtx;
+
+	void (*onLeaveRoomCb)(void *context, int reason, const char *message);
+	void *onLeaveRoomCtx;
+
+	void (*onTeamAddCb)(void *context, const flib_team *team);
+	void *onTeamAddCtx;
+
+	void (*onTeamDeleteCb)(void *context, const char *teamname);
+	void *onTeamDeleteCtx;
+
+	void (*onRunGameCb)(void *context);
+	void *onRunGameCtx;
+
+	void (*onTeamAcceptedCb)(void *context, const char *teamName);
+	void *onTeamAcceptedCtx;
+
+	void (*onHogCountChangedCb)(void *context, const char *teamName, int hogs);
+	void *onHogCountChangedCtx;
+
+	void (*onTeamColorChangedCb)(void *context, const char *teamName, int colorIndex);
+	void *onTeamColorChangedCtx;
+
+	void (*onEngineMessageCb)(void *context, const uint8_t *message, size_t size);
+	void *onEngineMessageCtx;
+
+	void (*onSchemeChangedCb)(void *context, const flib_scheme *scheme);
+	void *onSchemeChangedCtx;
+
+	void (*onMapChangedCb)(void *context, const flib_map *map, int changetype);
+	void *onMapChangedCtx;
+
+	void (*onScriptChangedCb)(void *context, const char *script);
+	void *onScriptChangedCtx;
+
+	void (*onWeaponsetChangedCb)(void *context, const flib_weaponset *weaponset);
+	void *onWeaponsetChangedCtx;
+
+	void (*onServerVarCb)(void *context, const char *name, const char *value);
+	void *onServerVarCtx;
+
+	bool running;
+	bool destroyRequested;
+};
+
+void netconn_clearCallbacks(flib_netconn *conn);
+void netconn_leaveRoom(flib_netconn *conn);
+void netconn_setMap(flib_netconn *conn, const flib_map *map);
+void netconn_setWeaponset(flib_netconn *conn, const flib_weaponset *weaponset);
+void netconn_setScript(flib_netconn *conn, const char *script);
+void netconn_setScheme(flib_netconn *conn, const flib_scheme *scheme);
+
+#endif
diff --git a/project_files/frontlib/net/netconn_send.c b/project_files/frontlib/net/netconn_send.c
new file mode 100644
index 0000000..960808b
--- /dev/null
+++ b/project_files/frontlib/net/netconn_send.c
@@ -0,0 +1,495 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "netconn_internal.h"
+
+#include "../util/logging.h"
+#include "../util/util.h"
+#include "../util/buffer.h"
+#include "../md5/md5.h"
+#include "../base64/base64.h"
+
+#include <zlib.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+// cmdname is always given as literal from functions in this file, so it is never null.
+static int sendVoid(flib_netconn *conn, const char *cmdname) {
+	if(log_e_if(!conn, "Invalid parameter sending %s command", cmdname)) {
+		return -1;
+	}
+	return flib_netbase_sendf(conn->netBase, "%s\n\n", cmdname);
+}
+
+// Testing for !*str prevents sending 0-length parameters (they trip up the protocol)
+static int sendStr(flib_netconn *conn, const char *cmdname, const char *str) {
+	if(log_e_if(!conn || flib_strempty(str), "Invalid parameter sending %s command", cmdname)) {
+		return -1;
+	}
+	return flib_netbase_sendf(conn->netBase, "%s\n%s\n\n", cmdname, str);
+}
+
+static int sendInt(flib_netconn *conn, const char *cmdname, int param) {
+	if(log_e_if(!conn, "Invalid parameter sending %s command", cmdname)) {
+		return -1;
+	}
+	return flib_netbase_sendf(conn->netBase, "%s\n%i\n\n", cmdname, param);
+}
+
+int flib_netconn_send_nick(flib_netconn *conn, const char *nick) {
+	int result = -1;
+	if(!log_badargs_if2(conn==NULL, flib_strempty(nick))) {
+		char *tmpName = flib_strdupnull(nick);
+		if(tmpName) {
+			if(!flib_netbase_sendf(conn->netBase, "%s\n%s\n\n", "NICK", nick)) {
+				free(conn->playerName);
+				conn->playerName = tmpName;
+				tmpName = NULL;
+				result = 0;
+			}
+		}
+		free(tmpName);
+	}
+	return result;
+}
+
+int flib_netconn_send_password(flib_netconn *conn, const char *passwd) {
+	int result = -1;
+	if(!log_badargs_if2(conn==NULL, passwd==NULL)) {
+		md5_state_t md5state;
+		uint8_t md5bytes[16];
+		char md5hex[33];
+		md5_init(&md5state);
+		md5_append(&md5state, (unsigned char*)passwd, strlen(passwd));
+		md5_finish(&md5state, md5bytes);
+		for(int i=0;i<sizeof(md5bytes); i++) {
+			// Needs to be lowercase - server checks case sensitive
+			snprintf(md5hex+i*2, 3, "%02x", (unsigned)md5bytes[i]);
+		}
+		result = flib_netbase_sendf(conn->netBase, "%s\n%s\n\n", "PASSWORD", md5hex);
+	}
+	return result;
+}
+
+int flib_netconn_send_quit(flib_netconn *conn, const char *quitmsg) {
+	return sendStr(conn, "QUIT", (quitmsg && *quitmsg) ? quitmsg : "User quit");
+}
+
+int flib_netconn_send_chat(flib_netconn *conn, const char *chat) {
+	if(!flib_strempty(chat)) {
+		return sendStr(conn, "CHAT", chat);
+	}
+	return 0;
+}
+
+int flib_netconn_send_kick(flib_netconn *conn, const char *playerName) {
+	return sendStr(conn, "KICK", playerName);
+}
+
+int flib_netconn_send_playerInfo(flib_netconn *conn, const char *playerName) {
+	return sendStr(conn, "INFO", playerName);
+}
+
+int flib_netconn_send_request_roomlist(flib_netconn *conn) {
+	return sendVoid(conn, "LIST");
+}
+
+int flib_netconn_send_joinRoom(flib_netconn *conn, const char *room) {
+	if(!sendStr(conn, "JOIN_ROOM", room)) {
+		conn->isChief = false;
+		return 0;
+	}
+	return -1;
+}
+
+int flib_netconn_send_playerFollow(flib_netconn *conn, const char *playerName) {
+	return sendStr(conn, "FOLLOW", playerName);
+}
+
+int flib_netconn_send_createRoom(flib_netconn *conn, const char *room) {
+	if(!sendStr(conn, "CREATE_ROOM", room)) {
+		conn->isChief = true;
+		return 0;
+	}
+	return -1;
+}
+
+int flib_netconn_send_ban(flib_netconn *conn, const char *playerName) {
+	return sendStr(conn, "BAN", playerName);
+}
+
+int flib_netconn_send_clearAccountsCache(flib_netconn *conn) {
+	return sendVoid(conn, "CLEAR_ACCOUNTS_CACHE");
+}
+
+int flib_netconn_send_setServerVar(flib_netconn *conn, const char *name, const char *value) {
+	if(log_badargs_if3(conn==NULL, flib_strempty(name), flib_strempty(value))) {
+		return -1;
+	}
+	return flib_netbase_sendf(conn->netBase, "%s\n%s\n%s\n\n", "SET_SERVER_VAR", name, value);
+}
+
+int flib_netconn_send_getServerVars(flib_netconn *conn) {
+	return sendVoid(conn, "GET_SERVER_VAR");
+}
+int flib_netconn_send_leaveRoom(flib_netconn *conn, const char *str) {
+	int result = -1;
+	if(conn->netconnState==NETCONN_STATE_ROOM) {
+		result = (str && *str) ? sendStr(conn, "PART", str) : sendVoid(conn, "PART");
+		if(!result) {
+			netconn_leaveRoom(conn);
+		}
+	}
+	return result;
+}
+
+int flib_netconn_send_toggleReady(flib_netconn *conn) {
+	return sendVoid(conn, "TOGGLE_READY");
+}
+
+static void addTeamToPendingList(flib_netconn *conn, const flib_team *team) {
+	flib_team *teamcopy = flib_team_copy(team);
+	if(teamcopy) {
+		teamcopy->remoteDriven = false;
+		free(teamcopy->ownerName);
+		teamcopy->ownerName = flib_strdupnull(conn->playerName);
+		if(teamcopy->ownerName) {
+			flib_teamlist_delete(&conn->pendingTeamlist, team->name);
+			if(!flib_teamlist_insert(&conn->pendingTeamlist, teamcopy, 0)) {
+				teamcopy = NULL;
+			}
+		}
+	}
+	flib_team_destroy(teamcopy);
+}
+
+int flib_netconn_send_addTeam(flib_netconn *conn, const flib_team *team) {
+	int result = -1;
+	if(!log_badargs_if2(conn==NULL, team==NULL)) {
+		bool missingInfo = flib_strempty(team->name) || flib_strempty(team->grave) || flib_strempty(team->fort) || flib_strempty(team->voicepack) || flib_strempty(team->flag);
+		for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) {
+			missingInfo |= flib_strempty(team->hogs[i].name) || flib_strempty(team->hogs[i].hat);
+		}
+		if(!log_e_if(missingInfo, "Incomplete team definition")) {
+			flib_vector *vec = flib_vector_create();
+			if(vec) {
+				bool error = false;
+				error |= flib_vector_appendf(vec, "ADD_TEAM\n%s\n%i\n%s\n%s\n%s\n%s\n%i\n", team->name, team->colorIndex, team->grave, team->fort, team->voicepack, team->flag, team->hogs[0].difficulty);
+				for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) {
+					error |= flib_vector_appendf(vec, "%s\n%s\n", team->hogs[i].name, team->hogs[i].hat);
+				}
+				error |= flib_vector_appendf(vec, "\n");
+				if(!error && !flib_netbase_send_raw(conn->netBase, flib_vector_data(vec), flib_vector_size(vec))) {
+					addTeamToPendingList(conn, team);
+					result = 0;
+				}
+			}
+			flib_vector_destroy(vec);
+		}
+	}
+	return result;
+}
+
+int flib_netconn_send_removeTeam(flib_netconn *conn, const char *teamname) {
+	flib_team *team = flib_teamlist_find(&conn->teamlist, teamname);
+	if(team && !team->remoteDriven && !sendStr(conn, "REMOVE_TEAM", teamname)) {
+		flib_teamlist_delete(&conn->teamlist, teamname);
+		return 0;
+	}
+	return -1;
+}
+
+int flib_netconn_send_renameRoom(flib_netconn *conn, const char *roomName) {
+	return sendStr(conn, "ROOM_NAME", roomName);
+}
+
+int flib_netconn_send_teamHogCount(flib_netconn *conn, const char *teamname, int hogcount) {
+	if(!log_badargs_if5(conn==NULL, flib_strempty(teamname), hogcount<1, hogcount>HEDGEHOGS_PER_TEAM, !conn->isChief)
+			&& !flib_netbase_sendf(conn->netBase, "HH_NUM\n%s\n%i\n\n", teamname, hogcount)) {
+		flib_team *team = flib_teamlist_find(&conn->teamlist, teamname);
+		if(team) {
+			team->hogsInGame = hogcount;
+		}
+		return 0;
+	}
+	return -1;
+}
+
+int flib_netconn_send_teamColor(flib_netconn *conn, const char *teamname, int colorIndex) {
+	if(!log_badargs_if3(conn==NULL, flib_strempty(teamname), !conn->isChief)
+			&& !flib_netbase_sendf(conn->netBase, "TEAM_COLOR\n%s\n%i\n\n", teamname, colorIndex)) {
+		flib_team *team = flib_teamlist_find(&conn->teamlist, teamname);
+		if(team) {
+			team->colorIndex = colorIndex;
+		}
+		return 0;
+	}
+	return -1;
+}
+
+int flib_netconn_send_weaponset(flib_netconn *conn, const flib_weaponset *weaponset) {
+	if(!log_badargs_if3(conn==NULL, weaponset==NULL, flib_strempty(weaponset->name))) {
+		char ammostring[WEAPONS_COUNT*4+1];
+		strcpy(ammostring, weaponset->loadout);
+		strcat(ammostring, weaponset->crateprob);
+		strcat(ammostring, weaponset->delay);
+		strcat(ammostring, weaponset->crateammo);
+		if(conn->isChief) {
+			if(!flib_netbase_sendf(conn->netBase, "CFG\nAMMO\n%s\n%s\n\n", weaponset->name, ammostring)) {
+				netconn_setWeaponset(conn, weaponset);
+				return 0;
+			}
+		}
+	}
+	return -1;
+}
+
+int flib_netconn_send_map(flib_netconn *conn, const flib_map *map) {
+	if(log_badargs_if2(conn==NULL, map==NULL)) {
+		return -1;
+	}
+	bool error = false;
+
+	if(map->seed) {
+		error |= flib_netconn_send_mapSeed(conn, map->seed);
+	}
+	error |= flib_netconn_send_mapTemplate(conn, map->templateFilter);
+	if(map->theme) {
+		error |= flib_netconn_send_mapTheme(conn, map->theme);
+	}
+	error |= flib_netconn_send_mapGen(conn, map->mapgen);
+	error |= flib_netconn_send_mapMazeSize(conn, map->mazeSize);
+	if(map->drawData && map->drawDataSize>0) {
+		error |= flib_netconn_send_mapDrawdata(conn, map->drawData, map->drawDataSize);
+	}
+	// Name is sent last, because the QtFrontend uses this to update its preview, and to show/hide
+	// certain fields
+	if(map->name) {
+		error |= flib_netconn_send_mapName(conn, map->name);
+	}
+	return error;
+}
+
+int flib_netconn_send_mapName(flib_netconn *conn, const char *mapName) {
+	if(log_badargs_if2(conn==NULL, mapName==NULL)) {
+		return -1;
+	}
+	if(conn->isChief) {
+		if(!sendStr(conn, "CFG\nMAP", mapName)) {
+			char *copy = flib_strdupnull(mapName);
+			if(copy) {
+				free(conn->map->name);
+				conn->map->name = copy;
+				return 0;
+			}
+		}
+	}
+	return -1;
+}
+
+int flib_netconn_send_mapGen(flib_netconn *conn, int mapGen) {
+	if(log_badargs_if(conn==NULL)) {
+		return -1;
+	}
+	if(conn->isChief) {
+		if(!sendInt(conn, "CFG\nMAPGEN", mapGen)) {
+			conn->map->mapgen = mapGen;
+			return 0;
+		}
+	}
+	return -1;
+}
+
+int flib_netconn_send_mapTemplate(flib_netconn *conn, int templateFilter) {
+	if(log_badargs_if(conn==NULL)) {
+		return -1;
+	}
+	if(conn->isChief) {
+		if(!sendInt(conn, "CFG\nTEMPLATE", templateFilter)) {
+			conn->map->templateFilter = templateFilter;
+			return 0;
+		}
+	}
+	return -1;
+}
+
+int flib_netconn_send_mapMazeSize(flib_netconn *conn, int mazeSize) {
+	if(log_badargs_if(conn==NULL)) {
+		return -1;
+	}
+	if(conn->isChief) {
+		if(!sendInt(conn, "CFG\nMAZE_SIZE", mazeSize)) {
+			conn->map->mazeSize = mazeSize;
+			return 0;
+		}
+	}
+	return -1;
+}
+
+int flib_netconn_send_mapSeed(flib_netconn *conn, const char *seed) {
+	if(log_badargs_if2(conn==NULL, seed==NULL)) {
+		return -1;
+	}
+	if(conn->isChief) {
+		if(!sendStr(conn, "CFG\nSEED", seed)) {
+			char *copy = flib_strdupnull(seed);
+			if(copy) {
+				free(conn->map->seed);
+				conn->map->seed = copy;
+				return 0;
+			}
+		}
+	}
+	return -1;
+}
+
+int flib_netconn_send_mapTheme(flib_netconn *conn, const char *theme) {
+	if(log_badargs_if2(conn==NULL, theme==NULL)) {
+		return -1;
+	}
+	if(conn->isChief) {
+		if(!sendStr(conn, "CFG\nTHEME", theme)) {
+			char *copy = flib_strdupnull(theme);
+			if(copy) {
+				free(conn->map->theme);
+				conn->map->theme = copy;
+				return 0;
+			}
+		}
+	}
+	return -1;
+}
+
+int flib_netconn_send_mapDrawdata(flib_netconn *conn, const uint8_t *drawData, size_t size) {
+	int result = -1;
+	if(!log_badargs_if3(conn==NULL, drawData==NULL && size>0, size>SIZE_MAX/2) && conn->isChief) {
+		uLongf zippedSize = compressBound(size);
+		uint8_t *zipped = flib_malloc(zippedSize+4); // 4 extra bytes for header
+		if(zipped) {
+			// Create the QCompress size header (uint32 big endian)
+			zipped[0] = (size>>24) & 0xff;
+			zipped[1] = (size>>16) & 0xff;
+			zipped[2] = (size>>8) & 0xff;
+			zipped[3] = (size) & 0xff;
+
+			if(compress(zipped+4, &zippedSize, drawData, size) != Z_OK) {
+				flib_log_e("Error compressing drawn map data.");
+			} else {
+				char *base64encout = NULL;
+				base64_encode_alloc((const char*)zipped, zippedSize+4, &base64encout);
+				if(!base64encout) {
+					flib_log_e("Error base64-encoding drawn map data.");
+				} else {
+					result = flib_netbase_sendf(conn->netBase, "CFG\nDRAWNMAP\n%s\n\n", base64encout);
+				}
+				free(base64encout);
+			}
+		}
+		free(zipped);
+	}
+
+	if(!result) {
+		uint8_t *copy = flib_bufdupnull(drawData, size);
+		if(copy) {
+			free(conn->map->drawData);
+			conn->map->drawData = copy;
+			conn->map->drawDataSize = size;
+		}
+	}
+	return result;
+}
+
+int flib_netconn_send_script(flib_netconn *conn, const char *scriptName) {
+	if(log_badargs_if2(conn==NULL, scriptName==NULL)) {
+		return -1;
+	}
+	if(conn->isChief) {
+		if(!sendStr(conn, "CFG\nSCRIPT", scriptName)) {
+			netconn_setScript(conn, scriptName);
+			return 0;
+		}
+	}
+	return -1;
+}
+
+int flib_netconn_send_scheme(flib_netconn *conn, const flib_scheme *scheme) {
+	int result = -1;
+	if(!log_badargs_if3(conn==NULL, scheme==NULL, flib_strempty(scheme->name)) && conn->isChief) {
+		flib_vector *vec = flib_vector_create();
+		if(vec) {
+			bool error = false;
+			error |= flib_vector_appendf(vec, "CFG\nSCHEME\n%s\n", scheme->name);
+			for(int i=0; i<flib_meta.modCount; i++) {
+				error |= flib_vector_appendf(vec, "%s\n", scheme->mods[i] ? "true" : "false");
+			}
+			for(int i=0; i<flib_meta.settingCount; i++) {
+				error |= flib_vector_appendf(vec, "%i\n", scheme->settings[i]);
+			}
+			error |= flib_vector_appendf(vec, "\n");
+			if(!error) {
+				result = flib_netbase_send_raw(conn->netBase, flib_vector_data(vec), flib_vector_size(vec));
+			}
+		}
+		flib_vector_destroy(vec);
+	}
+
+	if(!result) {
+		netconn_setScheme(conn, scheme);
+	}
+	return result;
+}
+
+int flib_netconn_send_startGame(flib_netconn *conn) {
+	return sendVoid(conn, "START_GAME");
+}
+
+int flib_netconn_send_toggleRestrictJoins(flib_netconn *conn) {
+	return sendVoid(conn, "TOGGLE_RESTRICT_JOINS");
+}
+
+int flib_netconn_send_toggleRestrictTeams(flib_netconn *conn) {
+	return sendVoid(conn, "TOGGLE_RESTRICT_TEAMS");
+}
+
+int flib_netconn_send_teamchat(flib_netconn *conn, const char *chat) {
+	if(!flib_strempty(chat)) {
+		return sendStr(conn, "TEAMCHAT", chat);
+	}
+	return 0;
+}
+
+int flib_netconn_send_engineMessage(flib_netconn *conn, const uint8_t *message, size_t size) {
+	int result = -1;
+	if(!log_badargs_if2(conn==NULL, message==NULL && size>0)) {
+		char *base64encout = NULL;
+		base64_encode_alloc((const char*)message, size, &base64encout);
+		if(base64encout) {
+			result = flib_netbase_sendf(conn->netBase, "EM\n%s\n\n", base64encout);
+		}
+		free(base64encout);
+	}
+	return result;
+}
+
+int flib_netconn_send_roundfinished(flib_netconn *conn, bool withoutError) {
+	return sendInt(conn, "ROUNDFINISHED", withoutError ? 1 : 0);
+}
+
diff --git a/project_files/frontlib/net/netprotocol.c b/project_files/frontlib/net/netprotocol.c
new file mode 100644
index 0000000..9dd4dab
--- /dev/null
+++ b/project_files/frontlib/net/netprotocol.c
@@ -0,0 +1,192 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "netprotocol.h"
+
+#include "../util/util.h"
+#include "../util/logging.h"
+
+#include "../base64/base64.h"
+
+#include <zlib.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+
+static int fillTeamFromMsg(flib_team *team, char **parts) {
+	team->name = flib_strdupnull(parts[0]);
+	team->grave = flib_strdupnull(parts[1]);
+	team->fort = flib_strdupnull(parts[2]);
+	team->voicepack = flib_strdupnull(parts[3]);
+	team->flag = flib_strdupnull(parts[4]);
+	team->ownerName = flib_strdupnull(parts[5]);
+	if(!team->name || !team->grave || !team->fort || !team->voicepack || !team->flag || !team->ownerName) {
+		return -1;
+	}
+
+	errno = 0;
+	long difficulty = strtol(parts[6], NULL, 10);
+	if(errno) {
+		return -1;
+	}
+
+	for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) {
+		flib_hog *hog = &team->hogs[i];
+		hog->difficulty = difficulty;
+		hog->name = flib_strdupnull(parts[7+2*i]);
+		hog->hat = flib_strdupnull(parts[8+2*i]);
+		if(!hog->name || !hog->hat) {
+			return -1;
+		}
+	}
+
+	// Set some default assumptions as well
+	team->colorIndex = DEFAULT_COLOR_INDEX;
+	team->hogsInGame = DEFAULT_HEDGEHOG_COUNT;
+	team->remoteDriven = true;
+	return 0;
+}
+
+flib_team *flib_team_from_netmsg(char **parts) {
+	flib_team *result = NULL;
+	flib_team *tmpTeam = flib_calloc(1, sizeof(flib_team));
+	if(tmpTeam) {
+		if(!fillTeamFromMsg(tmpTeam, parts)) {
+			result = tmpTeam;
+			tmpTeam = NULL;
+		} else {
+			flib_log_e("Error parsing team from net.");
+		}
+	}
+	flib_team_destroy(tmpTeam);
+	return result;
+}
+
+flib_scheme *flib_scheme_from_netmsg(char **parts) {
+	flib_scheme *result = flib_scheme_create(parts[0]);
+	if(result) {
+		for(int i=0; i<flib_meta.modCount; i++) {
+			result->mods[i] = !strcmp(parts[i+1], "true");
+		}
+		for(int i=0; i<flib_meta.settingCount; i++) {
+			result->settings[i] = atoi(parts[i+flib_meta.modCount+1]);
+		}
+	}
+	return result;
+}
+
+flib_map *flib_map_from_netmsg(char **parts) {
+	flib_map *result = flib_map_create_named(parts[3], parts[0]);
+	if(result) {
+		result->mapgen = atoi(parts[1]);
+		result->mazeSize = atoi(parts[2]);
+		result->templateFilter = atoi(parts[4]);
+	}
+	return result;
+}
+
+int flib_drawnmapdata_from_netmsg(char *netmsg, uint8_t** outbuf, size_t *outlen) {
+	int result = -1;
+
+	// First step: base64 decoding
+	char *base64decout = NULL;
+	size_t base64declen;
+	bool ok = base64_decode_alloc(netmsg, strlen(netmsg), &base64decout, &base64declen);
+	if(ok && base64declen>3) {
+		// Second step: unzip with the QCompress header. That header is just a big-endian
+		// uint32 indicating the length of the uncompressed data.
+		uint8_t *ubyteBuf = (uint8_t*)base64decout;
+		uint32_t unzipLen =
+				(((uint32_t)ubyteBuf[0])<<24)
+				+ (((uint32_t)ubyteBuf[1])<<16)
+				+ (((uint32_t)ubyteBuf[2])<<8)
+				+ ubyteBuf[3];
+		if(unzipLen==0) {
+			*outbuf = NULL;
+			*outlen = 0;
+			result = 0;
+		} else {
+			uint8_t *out = flib_malloc(unzipLen);
+			if(out) {
+				uLongf actualUnzipLen = unzipLen;
+				int resultcode = uncompress(out, &actualUnzipLen, (Bytef*)(base64decout+4), base64declen-4);
+				if(resultcode == Z_OK) {
+					*outbuf = out;
+					*outlen = actualUnzipLen;
+					out = NULL;
+					result = 0;
+				} else {
+					flib_log_e("Uncompressing drawn map failed. Code: %i", resultcode);
+				}
+			}
+			free(out);
+		}
+	} else {
+		flib_log_e("base64 decoding of drawn map failed.");
+	}
+	free(base64decout);
+	return result;
+}
+
+flib_room *flib_room_from_netmsg(char **params) {
+	flib_room *result = NULL;
+	flib_room *tmpRoom = flib_calloc(1, sizeof(flib_room));
+	if(tmpRoom) {
+		tmpRoom->inProgress = !strcmp(params[0], "True");
+		tmpRoom->name = flib_strdupnull(params[1]);
+		tmpRoom->playerCount = atoi(params[2]);
+		tmpRoom->teamCount = atoi(params[3]);
+		tmpRoom->owner = flib_strdupnull(params[4]);
+		tmpRoom->map = flib_strdupnull(params[5]);
+		tmpRoom->scheme = flib_strdupnull(params[6]);
+		tmpRoom->weapons = flib_strdupnull(params[7]);
+		if(tmpRoom->name && tmpRoom->owner && tmpRoom->map && tmpRoom->scheme && tmpRoom->weapons) {
+			result = tmpRoom;
+			tmpRoom = NULL;
+		}
+	}
+	flib_room_destroy(tmpRoom);
+	return result;
+}
+
+int fillRoomArray(flib_room **array, char **params, int count) {
+	for(int i=0; i<count; i++) {
+		array[i] = flib_room_from_netmsg(params + 8*i);
+		if(!array[i]) {
+			return -1;
+		}
+	}
+	return 0;
+}
+
+flib_room **flib_room_array_from_netmsg(char **params, int count) {
+	flib_room **result = flib_calloc(count, sizeof(flib_room*));
+	if(result) {
+		if(fillRoomArray(result, params, count)) {
+			for(int i=0; i<count; i++) {
+				flib_room_destroy(result[i]);
+			}
+			free(result);
+			result = NULL;
+		}
+	}
+	return result;
+}
diff --git a/project_files/frontlib/net/netprotocol.h b/project_files/frontlib/net/netprotocol.h
new file mode 100644
index 0000000..de958e2
--- /dev/null
+++ b/project_files/frontlib/net/netprotocol.h
@@ -0,0 +1,66 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef NETPROTOCOL_H_
+#define NETPROTOCOL_H_
+
+#include "../model/team.h"
+#include "../model/scheme.h"
+#include "../model/map.h"
+#include "../model/room.h"
+
+#include <stddef.h>
+
+/**
+ * Create a new team from this 23-part net message
+ */
+flib_team *flib_team_from_netmsg(char **parts);
+
+/**
+ * Create a new scheme from this net message, which must have
+ * meta->modCount+meta->settingCount+1 parts.
+ */
+flib_scheme *flib_scheme_from_netmsg(char **parts);
+
+/**
+ * Create a new map from this five-part netmsg
+ */
+flib_map *flib_map_from_netmsg(char **parts);
+
+/**
+ * Decode the drawn map data from this netmessage line.
+ *
+ * The data is first base64 decoded and then quncompress()ed.
+ * The return value is a newly allocated byte buffer, the length
+ * is written to the variable pointed to by outlen.
+ * Returns NULL on error.
+ */
+int flib_drawnmapdata_from_netmsg(char *netmsg, uint8_t **outbuf, size_t *outlen);
+
+/**
+ * Create a new room from this 8-part net message
+ */
+flib_room *flib_room_from_netmsg(char **params);
+
+/**
+ * Create an array of count rooms from count*8 netmessage parts
+ */
+flib_room **flib_room_array_from_netmsg(char **params, int count);
+
+#endif /* NETPROTOCOL_H_ */
diff --git a/project_files/frontlib/socket.c b/project_files/frontlib/socket.c
new file mode 100644
index 0000000..caf1bc8
--- /dev/null
+++ b/project_files/frontlib/socket.c
@@ -0,0 +1,191 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "socket.h"
+#include "util/logging.h"
+#include "util/util.h"
+#include <stdlib.h>
+#include <SDL_net.h>
+#include <time.h>
+
+struct _flib_tcpsocket {
+	TCPsocket sock;
+	SDLNet_SocketSet sockset;
+};
+
+struct _flib_acceptor {
+	TCPsocket sock;
+	uint16_t port;
+};
+
+static uint32_t getPeerIp(TCPsocket sock) {
+	IPaddress *addr = SDLNet_TCP_GetPeerAddress(sock);
+	return SDLNet_Read32(&addr->host);
+}
+
+static bool connectionIsLocal(TCPsocket sock) {
+	return getPeerIp(sock) == (uint32_t)((127UL<<24)+1); // 127.0.0.1
+}
+
+static flib_tcpsocket *createSocket(TCPsocket sdlsock) {
+	flib_tcpsocket *result = flib_calloc(1, sizeof(flib_tcpsocket));
+	if(result) {
+		result->sock = sdlsock;
+		result->sockset = SDLNet_AllocSocketSet(1);
+
+		if(!result->sockset) {
+			flib_log_e("Can't allocate socket: Out of memory!");
+			SDLNet_FreeSocketSet(result->sockset);
+			free(result);
+			result = NULL;
+		} else {
+			SDLNet_AddSocket(result->sockset, (SDLNet_GenericSocket)result->sock);
+		}
+	}
+	return result;
+}
+
+TCPsocket listen(uint16_t port) {
+	IPaddress addr;
+	addr.host = INADDR_ANY;
+	SDLNet_Write16(port, &addr.port);
+	TCPsocket sock = SDLNet_TCP_Open(&addr);
+	if(!sock) {
+		flib_log_w("Unable to listen on port %u: %s", (unsigned)port, SDLNet_GetError());
+	}
+	return sock;
+}
+
+flib_acceptor *flib_acceptor_create(uint16_t port) {
+	flib_acceptor *result = flib_calloc(1, sizeof(flib_acceptor));
+	if(result) {
+		if(port > 0) {
+			result->port = port;
+			result->sock = listen(result->port);
+		} else {
+			/* SDL_net does not seem to have a way to listen on a random unused port
+			   and find out which port that is, so let's try to find one ourselves. */
+			srand(time(NULL));
+			for(int i=0; !result->sock && i<1000; i++) {
+				// IANA suggests using ports in the range 49152-65535 for things like this
+				result->port = 49152+(rand()%(65536-49152));
+				result->sock = listen(result->port);
+			}
+		}
+		if(!result->sock) {
+			flib_log_e("Failed to create acceptor.");
+			free(result);
+			result = NULL;
+		}
+	}
+	return result;
+}
+
+uint16_t flib_acceptor_listenport(flib_acceptor *acceptor) {
+	if(!acceptor) {
+		flib_log_e("Call to flib_acceptor_listenport with acceptor==null");
+		return 0;
+	}
+	return acceptor->port;
+}
+
+void flib_acceptor_close(flib_acceptor *acceptor) {
+	if(acceptor) {
+		SDLNet_TCP_Close(acceptor->sock);
+		free(acceptor);
+	}
+}
+
+flib_tcpsocket *flib_socket_accept(flib_acceptor *acceptor, bool localOnly) {
+	flib_tcpsocket *result = NULL;
+	if(!acceptor) {
+		flib_log_e("Call to flib_socket_accept with acceptor==null");
+	} else {
+		TCPsocket sock = NULL;
+		while(!result && (sock = SDLNet_TCP_Accept(acceptor->sock))) {
+			if(localOnly && !connectionIsLocal(sock)) {
+				flib_log_i("Rejected nonlocal connection attempt from %s", flib_format_ip(getPeerIp(sock)));
+			} else {
+				result = createSocket(sock);
+			}
+			if(!result) {
+				SDLNet_TCP_Close(sock);
+			}
+		}
+	}
+	return result;
+}
+
+flib_tcpsocket *flib_socket_connect(const char *host, uint16_t port) {
+	flib_tcpsocket *result = NULL;
+	if(!host || port==0) {
+		flib_log_e("Invalid parameter in flib_socket_connect");
+	} else {
+		IPaddress ip;
+		if(SDLNet_ResolveHost(&ip,host,port)==-1) {
+		   flib_log_e("SDLNet_ResolveHost: %s\n", SDLNet_GetError());
+		} else {
+			TCPsocket sock=SDLNet_TCP_Open(&ip);
+			if(!sock) {
+				flib_log_e("SDLNet_TCP_Open: %s\n", SDLNet_GetError());
+			} else {
+				result = createSocket(sock);
+				if(result) {
+					sock = NULL;
+				}
+			}
+			SDLNet_TCP_Close(sock);
+		}
+	}
+	return result;
+}
+
+void flib_socket_close(flib_tcpsocket *sock) {
+	if(sock) {
+		SDLNet_DelSocket(sock->sockset, (SDLNet_GenericSocket)sock->sock);
+		SDLNet_TCP_Close(sock->sock);
+		SDLNet_FreeSocketSet(sock->sockset);
+		free(sock);
+	}
+}
+
+int flib_socket_nbrecv(flib_tcpsocket *sock, void *data, int maxlen) {
+	if(!sock || (maxlen>0 && !data)) {
+		flib_log_e("Call to flib_socket_nbrecv with sock==null or data==null");
+		return -1;
+	}
+	int readySockets = SDLNet_CheckSockets(sock->sockset, 0);
+	if(readySockets>0) {
+		int size = SDLNet_TCP_Recv(sock->sock, data, maxlen);
+		return size>0 ? size : -1;
+	} else if(readySockets==0) {
+		return 0;
+	} else {
+		flib_log_e("Error in select system call: %s", SDLNet_GetError());
+		return -1;
+	}
+}
+
+int flib_socket_send(flib_tcpsocket *sock, const void *data, int len) {
+	if(!sock || (len>0 && !data)) {
+		flib_log_e("Call to flib_socket_send with sock==null or data==null");
+		return -1;
+	}
+	return SDLNet_TCP_Send(sock->sock, data, len);
+}
diff --git a/project_files/frontlib/socket.h b/project_files/frontlib/socket.h
new file mode 100644
index 0000000..2c7496f
--- /dev/null
+++ b/project_files/frontlib/socket.h
@@ -0,0 +1,91 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/*
+ * Sockets for TCP networking.
+ *
+ * This layer offers some functionality over what SDL_net offers directly: listening
+ * sockets (called acceptors here) can be bound to port 0, which will make them listen
+ * on a random unused port, if one can be found. To support this feature, you can also
+ * query the local port that an acceptor is listening on.
+ *
+ * Further, we support nonblocking reads here.
+ */
+
+#ifndef SOCKET_H_
+#define SOCKET_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+
+typedef struct _flib_tcpsocket flib_tcpsocket;
+typedef struct _flib_acceptor flib_acceptor;
+
+/**
+ * Create a new acceptor which will listen for incoming TCP connections
+ * on the given port. If port is 0, this will listen on a random
+ * unused port which can then be queried with flib_acceptor_listenport.
+ *
+ * Returns NULL on error.
+ */
+flib_acceptor *flib_acceptor_create(uint16_t port);
+
+/**
+ * Return the port on which the acceptor is listening.
+ */
+uint16_t flib_acceptor_listenport(flib_acceptor *acceptor);
+
+/**
+ * Close the acceptor and free its memory. NULL-safe.
+ */
+void flib_acceptor_close(flib_acceptor *acceptor);
+
+/**
+ * Try to accept a connection from an acceptor (listening socket).
+ * if localOnly is true, this will only accept connections which came from 127.0.0.1
+ * Returns NULL if nothing can be accepted.
+ */
+flib_tcpsocket *flib_socket_accept(flib_acceptor *acceptor, bool localOnly);
+
+/**
+ * Try to connect to the server at the given address.
+ */
+flib_tcpsocket *flib_socket_connect(const char *host, uint16_t port);
+
+/**
+ * Close the socket and free its memory. NULL-safe.
+ */
+void flib_socket_close(flib_tcpsocket *socket);
+
+/**
+ * Attempt to receive up to maxlen bytes from the socket, but does not
+ * block if nothing is available.
+ * Returns the ammount of data received, 0 if there was nothing to receive,
+ * or a negative number if the connection was closed or an error occurred.
+ */
+int flib_socket_nbrecv(flib_tcpsocket *sock, void *data, int maxlen);
+
+/**
+ * Blocking send all the data in the data buffer. Returns the actual ammount
+ * of data sent, or a negative value on error. If the value returned here
+ * is less than len, either the connection closed or an error occurred.
+ */
+int flib_socket_send(flib_tcpsocket *sock, const void *data, int len);
+
+#endif /* SOCKET_H_ */
diff --git a/project_files/frontlib/util/buffer.c b/project_files/frontlib/util/buffer.c
new file mode 100644
index 0000000..50577d7
--- /dev/null
+++ b/project_files/frontlib/util/buffer.c
@@ -0,0 +1,177 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "buffer.h"
+#include "logging.h"
+#include "util.h"
+
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+
+#define MIN_VECTOR_CAPACITY 16
+
+struct _flib_vector {
+	void *data;
+	size_t size;
+	size_t capacity;
+};
+
+flib_vector *flib_vector_create() {
+	flib_vector *result = NULL;
+	flib_vector *tmpVector = flib_calloc(1, sizeof(flib_vector));
+	if(tmpVector) {
+		tmpVector->data = flib_malloc(MIN_VECTOR_CAPACITY);
+		if(tmpVector->data) {
+			tmpVector->size = 0;
+			tmpVector->capacity = MIN_VECTOR_CAPACITY;
+			result = tmpVector;
+			tmpVector = NULL;
+		}
+	}
+	flib_vector_destroy(tmpVector);
+	return result;
+}
+
+void flib_vector_destroy(flib_vector *vec) {
+	if(vec) {
+		free(vec->data);
+		free(vec);
+	}
+}
+
+static int setCapacity(flib_vector *vec, size_t newCapacity) {
+	if(newCapacity == vec->capacity) {
+		return 0;
+	}
+	void *newData = realloc(vec->data, newCapacity);
+	if(newData) {
+		vec->data = newData;
+		vec->capacity = newCapacity;
+		return 0;
+	} else {
+		return -1;
+	}
+}
+
+static int allocateExtraCapacity(flib_vector *vec, size_t extraCapacity) {
+	if(extraCapacity <= SIZE_MAX - vec->capacity) {
+		return setCapacity(vec, vec->capacity + extraCapacity);
+	} else {
+		return -1;
+	}
+}
+
+int flib_vector_resize(flib_vector *vec, size_t newSize) {
+	if(log_badargs_if(vec==NULL)) {
+		return -1;
+	}
+
+	if(vec->capacity < newSize) {
+		// Resize exponentially for constant amortized time,
+		// But at least by as much as we need of course
+		size_t extraCapacity = (vec->capacity)/2;
+		size_t minExtraCapacity = newSize - vec->capacity;
+		if(extraCapacity < minExtraCapacity) {
+			extraCapacity = minExtraCapacity;
+		}
+
+		if(allocateExtraCapacity(vec, extraCapacity)) {
+			allocateExtraCapacity(vec, minExtraCapacity);
+		}
+	} else if(vec->capacity/2 > newSize) {
+		size_t newCapacity = newSize+newSize/4;
+		if(newCapacity < MIN_VECTOR_CAPACITY) {
+			newCapacity = MIN_VECTOR_CAPACITY;
+		}
+		setCapacity(vec, newCapacity);
+	}
+
+	if(vec->capacity >= newSize) {
+		vec->size = newSize;
+		return 0;
+	} else {
+		return -1;
+	}
+}
+
+int flib_vector_append(flib_vector *vec, const void *data, size_t len) {
+	if(!log_badargs_if2(vec==NULL, data==NULL && len>0)
+			&& !log_oom_if(len > SIZE_MAX-vec->size)) {
+		size_t oldSize = vec->size;
+		if(!log_oom_if(flib_vector_resize(vec, vec->size+len))) {
+			memmove(((uint8_t*)vec->data) + oldSize, data, len);
+			return 0;
+		}
+	}
+	return -1;
+}
+
+int flib_vector_appendf(flib_vector *vec, const char *fmt, ...) {
+	int result = -1;
+	if(!log_badargs_if2(vec==NULL, fmt==NULL)) {
+		va_list argp;
+		va_start(argp, fmt);
+		char *formatted = flib_vasprintf(fmt, argp);
+		va_end(argp);
+
+
+		if(formatted) {
+			size_t len = strlen(formatted);
+			result = flib_vector_append(vec, formatted, len);
+		}
+	}
+	return result;
+}
+
+flib_buffer flib_vector_as_buffer(flib_vector *vec) {
+	if(log_badargs_if(vec==NULL)) {
+		flib_buffer result = {NULL, 0};
+		return result;
+	} else {
+		flib_buffer result = {vec->data, vec->size};
+		return result;
+	}
+}
+
+flib_constbuffer flib_vector_as_constbuffer(flib_vector *vec) {
+	if(log_badargs_if(vec==NULL)) {
+		flib_constbuffer result = {NULL, 0};
+		return result;
+	} else {
+		flib_constbuffer result = {vec->data, vec->size};
+		return result;
+	}
+}
+
+void *flib_vector_data(flib_vector *vec) {
+	if(log_badargs_if(vec==NULL)) {
+		return NULL;
+	} else {
+		return vec->data;
+	}
+}
+
+size_t flib_vector_size(flib_vector *vec) {
+	if(log_badargs_if(vec==NULL)) {
+		return 0;
+	} else {
+		return vec->size;
+	}
+}
diff --git a/project_files/frontlib/util/buffer.h b/project_files/frontlib/util/buffer.h
new file mode 100644
index 0000000..7e0af56
--- /dev/null
+++ b/project_files/frontlib/util/buffer.h
@@ -0,0 +1,104 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef BUFFER_H_
+#define BUFFER_H_
+
+#include <stdint.h>
+#include <stddef.h>
+
+/**
+ * A simple struct to hold both the pointer to an array and its size,
+ * for e.g. conveniently returning it from a function.
+ *
+ * Convention: Size is zero iff data is a NULL pointer.
+ */
+typedef struct {
+	void *data;
+	size_t size;
+} flib_buffer;
+
+/**
+ * Just like flib_buffer, but the contents are not supposed to be modified.
+ */
+typedef struct {
+	const void *data;
+	size_t size;
+} flib_constbuffer;
+
+/**
+ * Simple variable-capacity data structure that can be efficiently appended to.
+ */
+typedef struct _flib_vector flib_vector;
+
+/**
+ * Create a new vector. Needs to be destroyed again later with flib_vector_destroy.
+ * May return NULL if memory runs out.
+ */
+flib_vector *flib_vector_create();
+
+/**
+ * Free the memory of this vector
+ */
+void flib_vector_destroy(flib_vector *vec);
+
+/**
+ * Resize the vector. This changes the size, and ensures the capacity is large enough to
+ * for the new size. Can also free memory if the new size is smaller. There is no guarantee
+ * about the contents of extra memory.
+ */
+int flib_vector_resize(flib_vector *vec, size_t newSize);
+
+/**
+ * Append the provided data to the end of the vector, enlarging it as required.
+ * The vector remains unchanged if appending fails.
+ * Returns 0 on success.
+ */
+int flib_vector_append(flib_vector *vec, const void *data, size_t len);
+
+/**
+ * Append data from a format string to the buffer (without trailing 0)
+ * Returns 0 on success.
+ */
+int flib_vector_appendf(flib_vector *vec, const char *template, ...);
+
+/**
+ * Return a pointer to the current data buffer of the vector. This pointer can
+ * become invalid if the vector size or capacity is changed.
+ */
+void *flib_vector_data(flib_vector *vec);
+
+/**
+ * Return the current size of the vector.
+ */
+size_t flib_vector_size(flib_vector *vec);
+
+/**
+ * Return a buffer pointing to the current contents of the vector.
+ * These will become invalid if the vector size or capacity is changed.
+ */
+flib_buffer flib_vector_as_buffer(flib_vector *vec);
+
+/**
+ * Return a constbuffer pointing to the current contents of the vector.
+ * These will become invalid if the vector size or capacity is changed.
+ */
+flib_constbuffer flib_vector_as_constbuffer(flib_vector *vec);
+
+#endif
diff --git a/project_files/frontlib/util/inihelper.c b/project_files/frontlib/util/inihelper.c
new file mode 100644
index 0000000..5bcbd20
--- /dev/null
+++ b/project_files/frontlib/util/inihelper.c
@@ -0,0 +1,321 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "inihelper.h"
+#include "../iniparser/dictionary.h"
+#include "../iniparser/iniparser.h"
+
+#include "logging.h"
+#include "util.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <limits.h>
+#include <errno.h>
+#include <stdarg.h>
+
+struct _flib_ini {
+	dictionary *inidict;
+	char *currentSection;
+};
+
+static char *createDictKey(const char *sectionName, const char *keyName) {
+	return flib_asprintf("%s:%s", sectionName, keyName);
+}
+
+/**
+ * Turns a string into a lowercase string, in-place.
+ */
+static void strToLower(char *str) {
+	if(str) {
+		while(*str) {
+			*str = tolower(*str);
+			str++;
+		}
+	}
+}
+
+flib_ini *flib_ini_create(const char *filename) {
+	flib_ini *result = NULL;
+	flib_ini *tmpIni = flib_calloc(1, sizeof(flib_ini));
+	if(tmpIni) {
+		if(filename) {
+			tmpIni->inidict = iniparser_load(filename);
+		}
+		if(!tmpIni->inidict) {
+			tmpIni->inidict = dictionary_new(0);
+		}
+		if(tmpIni->inidict) {
+			result = tmpIni;
+			tmpIni = NULL;
+		}
+	}
+	flib_ini_destroy(tmpIni);
+	return result;
+}
+
+flib_ini *flib_ini_load(const char *filename) {
+	flib_ini *result = NULL;
+	if(!log_badargs_if(filename==NULL)) {
+		flib_ini *tmpIni = flib_calloc(1, sizeof(flib_ini));
+		if(tmpIni) {
+			tmpIni->inidict = iniparser_load(filename);
+			if(tmpIni->inidict) {
+				result = tmpIni;
+				tmpIni = NULL;
+			}
+		}
+		flib_ini_destroy(tmpIni);
+	}
+	return result;
+}
+
+int flib_ini_save(flib_ini *ini, const char *filename) {
+	int result = INI_ERROR_OTHER;
+	if(!log_badargs_if2(ini==NULL, filename==NULL)) {
+		FILE *file = fopen(filename, "wb");
+		if(!file) {
+			flib_log_e("Error opening file \"%s\" for writing.", filename);
+		} else {
+			iniparser_dump_ini(ini->inidict, file);
+			if(fclose(file)) {
+				flib_log_e("Write error on ini file \"%s\"", filename);
+			} else {
+				result = 0;
+			}
+		}
+	}
+	return result;
+}
+
+void flib_ini_destroy(flib_ini *ini) {
+	if(ini) {
+		if(ini->inidict) {
+			iniparser_freedict(ini->inidict);
+		}
+		free(ini->currentSection);
+		free(ini);
+	}
+}
+
+int flib_ini_enter_section(flib_ini *ini, const char *section) {
+	int result = INI_ERROR_OTHER;
+	if(ini) {
+		free(ini->currentSection);
+		ini->currentSection = NULL;
+	}
+	if(!log_badargs_if2(ini==NULL, section==NULL)) {
+		if(!iniparser_find_entry(ini->inidict, section)) {
+			flib_log_d("Ini section %s not found", section);
+			result = INI_ERROR_NOTFOUND;
+		} else {
+			ini->currentSection = flib_strdupnull(section);
+			if(ini->currentSection) {
+				// Usually iniparser ignores case, but some section-handling functions don't,
+				// so we set it to lowercase manually
+				strToLower(ini->currentSection);
+				result = 0;
+			}
+		}
+	}
+	return result;
+}
+
+int flib_ini_create_section(flib_ini *ini, const char *section) {
+	int result = INI_ERROR_OTHER;
+	if(!log_badargs_if2(ini==NULL, section==NULL)) {
+		result = flib_ini_enter_section(ini, section);
+		if(result == INI_ERROR_NOTFOUND) {
+			if(iniparser_set(ini->inidict, section, NULL)) {
+				flib_log_e("Error creating ini section %s", section);
+				result = INI_ERROR_OTHER;
+			} else {
+				result = flib_ini_enter_section(ini, section);
+			}
+		}
+	}
+	return result;
+}
+
+/**
+ * The result is an internal string of the iniparser, don't free it.
+ */
+static char *findValue(dictionary *dict, const char *section, const char *key) {
+	char *result = NULL;
+	char *dictKey = createDictKey(section, key);
+	if(dictKey) {
+		result = iniparser_getstring(dict, dictKey, NULL);
+	}
+	free(dictKey);
+	return result;
+}
+
+int flib_ini_get_str(flib_ini *ini, char **outVar, const char *key) {
+	char *tmpValue = NULL;
+	int result = flib_ini_get_str_opt(ini, &tmpValue, key, NULL);
+	if(result==0) {
+		if(tmpValue == NULL) {
+			result = INI_ERROR_NOTFOUND;
+		} else {
+			*outVar = tmpValue;
+			tmpValue = NULL;
+		}
+	}
+	free(tmpValue);
+	return result;
+}
+
+int flib_ini_get_str_opt(flib_ini *ini, char **outVar, const char *key, const char *def) {
+	int result = INI_ERROR_OTHER;
+	if(!log_badargs_if4(ini==NULL, ini->currentSection==NULL, outVar==NULL, key==NULL)) {
+		const char *value = findValue(ini->inidict, ini->currentSection, key);
+		if(!value) {
+			value = def;
+		}
+		char *valueDup = flib_strdupnull(value);
+		if(valueDup || !def) {
+			*outVar = valueDup;
+			result = 0;
+		}
+	}
+	return result;
+}
+
+int flib_ini_get_int(flib_ini *ini, int *outVar, const char *key) {
+	char *tmpValue = NULL;
+	int result = flib_ini_get_str(ini, &tmpValue, key);
+	if(result==0) {
+		errno = 0;
+		long val = strtol(tmpValue, NULL, 10);
+		if(errno!=0 || val<INT_MIN || val>INT_MAX) {
+			flib_log_w("Cannot parse ini setting %s/%s = \"%s\" as integer.", ini->currentSection, key, tmpValue);
+			result = INI_ERROR_FORMAT;
+		} else {
+			*outVar = val;
+		}
+	}
+	free(tmpValue);
+	return result;
+}
+
+int flib_ini_get_int_opt(flib_ini *ini, int *outVar, const char *key, int def) {
+	int tmpValue;
+	int result = flib_ini_get_int(ini, &tmpValue, key);
+	if(result == 0) {
+		*outVar = tmpValue;
+	} else if(result == INI_ERROR_NOTFOUND || result == INI_ERROR_FORMAT) {
+		*outVar = def;
+		result = 0;
+	}
+	return result;
+}
+
+int flib_ini_get_bool(flib_ini *ini, bool *outVar, const char *key) {
+	char *tmpValue = NULL;
+	int result = flib_ini_get_str(ini, &tmpValue, key);
+	if(result==0) {
+		bool trueval = strchr("1tTyY", tmpValue[0]);
+		bool falseval = strchr("0fFnN", tmpValue[0]);
+		if(!trueval && !falseval) {
+			flib_log_w("ini setting %s/%s = \"%s\" is not a recognized truth value.", ini->currentSection, key, tmpValue);
+			result = INI_ERROR_FORMAT;
+		} else {
+			*outVar = trueval;
+		}
+	}
+	free(tmpValue);
+	return result;
+}
+
+int flib_ini_get_bool_opt(flib_ini *ini, bool *outVar, const char *key, bool def) {
+	bool tmpValue;
+	int result = flib_ini_get_bool(ini, &tmpValue, key);
+	if(result == 0) {
+		*outVar = tmpValue;
+	} else if(result == INI_ERROR_NOTFOUND || result == INI_ERROR_FORMAT) {
+		*outVar = def;
+		result = 0;
+	}
+	return result;
+}
+
+int flib_ini_set_str(flib_ini *ini, const char *key, const char *value) {
+	int result = INI_ERROR_OTHER;
+	if(!log_badargs_if4(ini==NULL, ini->currentSection==NULL, key==NULL, value==NULL)) {
+		char *dictKey = createDictKey(ini->currentSection, key);
+		if(dictKey) {
+			result = iniparser_set(ini->inidict, dictKey, value);
+			if(result) {
+				flib_log_e("Error setting ini entry %s to %s", dictKey, value);
+			}
+		}
+		free(dictKey);
+	}
+	return result;
+}
+
+int flib_ini_set_int(flib_ini *ini, const char *key, int value) {
+	int result = INI_ERROR_OTHER;
+	char *strvalue = flib_asprintf("%i", value);
+	if(strvalue) {
+		result = flib_ini_set_str(ini, key, strvalue);
+	}
+	free(strvalue);
+	return result;
+}
+
+int flib_ini_set_bool(flib_ini *ini, const char *key, bool value) {
+	return flib_ini_set_str(ini, key, value ? "true" : "false");
+}
+
+int flib_ini_get_sectioncount(flib_ini *ini) {
+	if(!log_badargs_if(ini==NULL)) {
+		return iniparser_getnsec(ini->inidict);
+	}
+	return INI_ERROR_OTHER;
+}
+
+char *flib_ini_get_sectionname(flib_ini *ini, int number) {
+	if(!log_badargs_if2(ini==NULL, number<0)) {
+		return flib_strdupnull(iniparser_getsecname(ini->inidict, number));
+	}
+	return NULL;
+}
+
+int flib_ini_get_keycount(flib_ini *ini) {
+	if(!log_badargs_if2(ini==NULL, ini->currentSection==NULL)) {
+		return iniparser_getsecnkeys(ini->inidict, ini->currentSection);
+	}
+	return INI_ERROR_OTHER;
+}
+
+char *flib_ini_get_keyname(flib_ini *ini, int number) {
+	char *result = NULL;
+	if(!log_badargs_if3(ini==NULL, ini->currentSection==NULL, number<0)) {
+		int keyCount = iniparser_getsecnkeys(ini->inidict, ini->currentSection);
+		char **keys = iniparser_getseckeys(ini->inidict, ini->currentSection);
+		if(keys && keyCount>number) {
+			// The keys are in the format section:key, so we have to skip the section and colon.
+			result = flib_strdupnull(keys[number]+strlen(ini->currentSection)+1);
+		}
+		free(keys);
+	}
+	return result;
+}
diff --git a/project_files/frontlib/util/inihelper.h b/project_files/frontlib/util/inihelper.h
new file mode 100644
index 0000000..3696187
--- /dev/null
+++ b/project_files/frontlib/util/inihelper.h
@@ -0,0 +1,178 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/**
+ * Convenience interface for ini reading/writing.
+ *
+ * We currently use iniparser in the background, but using its interface directly is a bit verbose.
+ * This module is supposed to 1. make ini reading and writing a bit more convenient, and 2. hide
+ * the iniparser dependency so it can at need be easily replaced.
+ */
+
+#ifndef INIHELPER_H_
+#define INIHELPER_H_
+
+#include <stdbool.h>
+
+#define INI_ERROR_NOTFOUND -1
+#define INI_ERROR_FORMAT -2
+#define INI_ERROR_OTHER -100
+
+typedef struct _flib_ini flib_ini;
+
+/**
+ * Create a new ini data structure, pre-filled with the contents of
+ * the file "filename" if it exists. If filename is null, or the file
+ * is not found, an empty ini will be created. However, if an error
+ * occurs while reading the ini file (or any other error), null
+ * is returned.
+ *
+ * This behavior is useful for modifying an existing ini file without
+ * discarding unknown keys.
+ */
+flib_ini *flib_ini_create(const char *filename);
+
+/**
+ * Similar to flib_ini_create, but fails if the file is not found
+ * or if filename is null.
+ */
+flib_ini *flib_ini_load(const char *filename);
+
+/**
+ * Store the ini to the file "filename", overwriting
+ * the previous contents. Returns 0 on success.
+ */
+int flib_ini_save(flib_ini *ini, const char *filename);
+
+void flib_ini_destroy(flib_ini *ini);
+
+/**
+ * Enter the section with the specified name. Returns 0 on
+ * success, INI_ERROR_NOTFOUND if the section does not exist
+ * and a different value if another error occurs.
+ * If an error occurs, there is no current section.
+ *
+ * The section name should only consist of letters and
+ * numbers.
+ */
+int flib_ini_enter_section(flib_ini *ini, const char *section);
+
+/**
+ * Creates and enters the section with the specified name. Simply
+ * enters the section if it exists already. Returns 0 on success
+ * and a different value if another error occurs.
+ * If an error occurs, there is no current section.
+ */
+int flib_ini_create_section(flib_ini *ini, const char *section);
+
+/**
+ * Find a key in the current section and store the value in outVar
+ * as a newly allocated string. Returns 0 on success, INI_ERROR_NOTFOUND
+ * if the key was not found and a different value for other errors,
+ * e.g. if there is no current section.
+ */
+int flib_ini_get_str(flib_ini *ini, char **outVar, const char *key);
+
+/**
+ * Find a key in the current section and store the value in outVar
+ * as a newly allocated string. If the key is not found, the default
+ * value will be used instead. Returns 0 on success.
+ */
+int flib_ini_get_str_opt(flib_ini *ini, char **outVar, const char *key, const char *def);
+
+/**
+ * Find a key in the current section and store the value in outVar
+ * as an int. Returns 0 on success, INI_ERROR_NOTFOUND
+ * if the key was not found, INI_ERROR_FORMAT if it was found but
+ * could not be converted to an int, and a different value for other
+ * errors, e.g. if there is no current section.
+ */
+int flib_ini_get_int(flib_ini *ini, int *outVar, const char *key);
+
+/**
+ * Find a key in the current section and store the value in outVar
+ * as an int. If the key is not found, the default value will be used instead.
+ * Returns 0 on success, INI_ERROR_FORMAT if the value was found but
+ * could not be converted to int, and another value otherwise.
+ */
+int flib_ini_get_int_opt(flib_ini *ini, int *outVar, const char *key, int def);
+
+/**
+ * Find a key in the current section and store the value in outVar
+ * as a bool. Treats everything beginning with "Y", "T" or "1" as true,
+ * everything starting with "N", "F" or "1" as false.
+ *
+ * Returns 0 on success, INI_ERROR_NOTFOUND if the key was not found,
+ * INI_ERROR_FORMAT if the value could not be interpreted as boolean,
+ * and another value otherwise.
+ */
+int flib_ini_get_bool(flib_ini *ini, bool *outVar, const char *key);
+
+/**
+ * Find a key in the current section and store the value in outVar
+ * as a bool. If the key is not found, the default value will be
+ * used instead. Returns 0 on success, INI_ERROR_FORMAT if the
+ * value could not be interpreted as boolean, and another value otherwise.
+ */
+int flib_ini_get_bool_opt(flib_ini *ini, bool *outVar, const char *key, bool def);
+
+/**
+ * In the current section, associate key with value. Returns 0 on success.
+ */
+int flib_ini_set_str(flib_ini *ini, const char *key, const char *value);
+
+/**
+ * In the current section, associate key with value. Returns 0 on success.
+ */
+int flib_ini_set_int(flib_ini *ini, const char *key, int value);
+
+/**
+ * In the current section, associate key with value. Returns 0 on success.
+ */
+int flib_ini_set_bool(flib_ini *ini, const char *key, bool value);
+
+/**
+ * Returns the number of sections in the ini file, or a negative value on error.
+ */
+int flib_ini_get_sectioncount(flib_ini *ini);
+
+/**
+ * Returns the name of the section, or NULL on error. The returned string must
+ * be free()d.
+ *
+ * Note: There is no guarantee that the order of the sections
+ * will remain stable if the ini is modified.
+ */
+char *flib_ini_get_sectionname(flib_ini *ini, int number);
+
+/**
+ * Returns the number of keys in the current section, or -1 on error.
+ */
+int flib_ini_get_keycount(flib_ini *ini);
+
+/**
+ * Returns the name of the key in the current section, or NULL on error.
+ * The returned string must be free()d.
+ *
+ * Note: There is no guarantee that the order of the keys in a section
+ * will remain stable if the ini is modified.
+ */
+char *flib_ini_get_keyname(flib_ini *ini, int number);
+
+#endif /* INIHELPER_H_ */
diff --git a/project_files/frontlib/util/list.h b/project_files/frontlib/util/list.h
new file mode 100644
index 0000000..35622b1
--- /dev/null
+++ b/project_files/frontlib/util/list.h
@@ -0,0 +1,80 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/**
+ * Simple dynamic array manipulation functions.
+ */
+
+#ifndef LIST_H_
+#define LIST_H_
+
+#include <stddef.h>
+#include <string.h>
+#include <stdlib.h>
+#include "util.h"
+#include "logging.h"
+
+/**
+ * Generate a static function that inserts a new value into a heap array of the given type,
+ * using realloc and memmove to increase the capacity and shift existing values.
+ * The function takes a pointer to the array variable and a pointer to the size variable
+ * because both can be changed by this operation (realloc / increment).
+ * The function returns 0 on success and leaves the array unchanged on error.
+ */
+#define GENERATE_STATIC_LIST_INSERT(fname, type) \
+	static int fname(type **listptr, int *listSizePtr, type element, int pos) { \
+		int result = -1; \
+		if(!log_badargs_if4(listptr==NULL, listSizePtr==NULL, pos < 0, pos > *listSizePtr)) { \
+			type *newList = flib_realloc(*listptr, ((*listSizePtr)+1)*sizeof(type)); \
+			if(newList) { \
+				memmove(newList + (pos+1), newList + pos, ((*listSizePtr)-pos)*sizeof(type)); \
+				newList[pos] = element; \
+				(*listSizePtr)++; \
+				*listptr = newList; \
+				result = 0; \
+			} \
+		} \
+		return result; \
+	}
+
+/**
+ * Generate a static function that deletes a value from a heap array of the given type,
+ * using realloc and memmove to decrease the capacity and shift existing values.
+ * The function takes a pointer to the array variable and a pointer to the size variable
+ * because both can be changed by this operation (realloc / decrement).
+ * The function returns 0 on success and leaves the array unchanged on error.
+ */
+#define GENERATE_STATIC_LIST_DELETE(fname, type) \
+	static int fname(type **listPtr, int *listSizePtr, int pos) { \
+		int result = -1; \
+		if(!log_badargs_if4(listPtr==NULL, listSizePtr==NULL, pos < 0, pos >= *listSizePtr)) { \
+			memmove((*listPtr) + pos, (*listPtr) + (pos+1), ((*listSizePtr)-(pos+1))*sizeof(type)); \
+			(*listSizePtr)--; \
+			\
+			size_t newCharSize = (*listSizePtr)*sizeof(type); \
+			type *newList = flib_realloc((*listPtr), newCharSize); \
+			if(newList || newCharSize==0) { \
+				(*listPtr) = newList; \
+			} /* If the realloc fails, just keep using the old buffer...*/ \
+			result = 0; \
+		} \
+		return result; \
+	}
+
+#endif /* LIST_H_ */
diff --git a/project_files/frontlib/util/logging.c b/project_files/frontlib/util/logging.c
new file mode 100644
index 0000000..e5aabff
--- /dev/null
+++ b/project_files/frontlib/util/logging.c
@@ -0,0 +1,145 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "logging.h"
+
+#include <time.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+static int flib_loglevel = FLIB_LOGLEVEL_INFO;
+static FILE *flib_logfile = NULL;
+void (*flib_logCallback)(int level, const char *msg) = NULL;
+
+char* flib_format_ip(uint32_t numip) {
+	static char ip[16];
+	snprintf(ip, 16, "%u.%u.%u.%u", (unsigned)(numip>>24), (unsigned)((numip>>16)&0xff), (unsigned)((numip>>8)&0xff), (unsigned)(numip&0xff));
+	return ip;
+}
+
+static inline FILE *flib_log_getfile() {
+	if(flib_logfile==NULL) {
+		return stdout;
+	} else {
+		return flib_logfile;
+	}
+}
+
+static int log_time(char *buffer) {
+    time_t timer;
+    struct tm* tm_info;
+
+    time(&timer);
+    tm_info = localtime(&timer);
+
+    return strftime(buffer, 25, "%Y-%m-%d %H:%M:%S", tm_info);
+}
+
+static char getPrefix(int level) {
+	switch(level) {
+	case FLIB_LOGLEVEL_ERROR: return 'E';
+	case FLIB_LOGLEVEL_WARNING: return 'W';
+	case FLIB_LOGLEVEL_INFO: return 'I';
+	case FLIB_LOGLEVEL_DEBUG: return 'D';
+	default: return '?';
+	}
+}
+
+static void _flib_vflog(const char *func, int level, const char *fmt, va_list args) {
+	if(level >= flib_loglevel) {
+		char logbuffer[1024];
+		logbuffer[0] = getPrefix(level);
+		logbuffer[1] = ' ';
+
+		int pos = 2;
+
+		int len = log_time(logbuffer+pos);
+		if(len>=0) {
+			pos += len;
+			if(pos>sizeof(logbuffer)-1) pos = sizeof(logbuffer)-1;
+		} else {
+			return;
+		}
+
+		len = snprintf(logbuffer+pos, sizeof(logbuffer)-pos, " [%-30s] ", func);
+		if(len>=0) {
+			pos += len;
+			if(pos>sizeof(logbuffer)-1) pos = sizeof(logbuffer)-1;
+		} else {
+			return;
+		}
+
+		len = vsnprintf(logbuffer+pos, sizeof(logbuffer)-pos, fmt, args);
+		if(len>=0) {
+			pos += len;
+			if(pos>sizeof(logbuffer)-1) pos = sizeof(logbuffer)-1;
+		} else {
+			return;
+		}
+
+		if(flib_logCallback != NULL) {
+			flib_logCallback(level, logbuffer);
+		} else {
+			FILE *logfile = flib_log_getfile();
+			fputs(logbuffer, logfile);
+			fputc('\n', logfile);
+			fflush(logfile);
+		}
+	}
+}
+
+void _flib_flog(const char *func, int level, const char *fmt, ...) {
+	va_list argp;
+	va_start(argp, fmt);
+	_flib_vflog(func, level, fmt, argp);
+	va_end(argp);
+}
+
+bool _flib_fassert(const char *func, int level, bool cond, const char *fmt, ...) {
+	if(!cond) {
+		va_list argp;
+		va_start(argp, fmt);
+		_flib_vflog(func, level, fmt, argp);
+		va_end(argp);
+	}
+	return !cond;
+}
+
+int flib_log_getLevel() {
+	return flib_loglevel;
+}
+
+void flib_log_setLevel(int level) {
+	flib_loglevel = level;
+}
+
+void flib_log_setFile(FILE *file) {
+	flib_logfile = file;
+	flib_logCallback = NULL;
+}
+
+bool flib_log_isActive(int level) {
+	return level >= flib_log_getLevel();
+}
+
+void flib_log_setCallback(void (*logCallback)(int level, const char *msg)) {
+	flib_logCallback = logCallback;
+	flib_logfile = NULL;
+}
diff --git a/project_files/frontlib/util/logging.h b/project_files/frontlib/util/logging.h
new file mode 100644
index 0000000..9b5292f
--- /dev/null
+++ b/project_files/frontlib/util/logging.h
@@ -0,0 +1,106 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef LOGGING_H_
+#define LOGGING_H_
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdbool.h>
+
+#define FLIB_LOGLEVEL_ALL -100
+#define FLIB_LOGLEVEL_DEBUG -1
+#define FLIB_LOGLEVEL_INFO 0
+#define FLIB_LOGLEVEL_WARNING 1
+#define FLIB_LOGLEVEL_ERROR 2
+#define FLIB_LOGLEVEL_NONE 100
+
+/**
+ * Returns a pointer to a static buffer, don't free or store.
+ */
+char* flib_format_ip(uint32_t numip);
+
+/**
+ * Evaluates the expression cond. If it is true, a formatted error will be logged.
+ * Returns true if an error is logged, false otherwise (i.e. the boolean value of the argument)
+ * Usage: log_e_if(errorHasHappened, "Format string", formatArg, ...);
+ */
+#define log_e_if(cond, ...) _flib_fassert(__func__, FLIB_LOGLEVEL_ERROR, !(bool)(cond), __VA_ARGS__)
+#define log_w_if(cond, ...) _flib_fassert(__func__, FLIB_LOGLEVEL_WARNING, !(bool)(cond), __VA_ARGS__)
+
+/**
+ * Helper macros for log_badargs_if
+ * The t parameters are the textual representation of the c parameters. They need to be passed
+ * explicitly, to prevent them from being expanded in prescan.
+ */
+#define _flib_lbi(c1,t1) log_e_if(c1, "Invalid Argument (%s)", t1)
+#define _flib_lbi2(c1,t1,c2,t2) (_flib_lbi(c1,t1) || _flib_lbi(c2,t2))
+#define _flib_lbi3(c1,t1,c2,t2,c3,t3) (_flib_lbi(c1,t1) || _flib_lbi2(c2,t2,c3,t3))
+#define _flib_lbi4(c1,t1,c2,t2,c3,t3,c4,t4) (_flib_lbi(c1,t1) || _flib_lbi3(c2,t2,c3,t3,c4,t4))
+#define _flib_lbi5(c1,t1,c2,t2,c3,t3,c4,t4,c5,t5) (_flib_lbi(c1,t1) || _flib_lbi4(c2,t2,c3,t3,c4,t4,c5,t5))
+#define _flib_lbi6(c1,t1,c2,t2,c3,t3,c4,t4,c5,t5,c6,t6) (_flib_lbi(c1,t1) || _flib_lbi5(c2,t2,c3,t3,c4,t4,c5,t5,c6,t6))
+
+/**
+ * These macros log an "Invalid Argument" error for the first of their arguments that evaluates to true.
+ * The text of the argument is included in the log message.
+ * The expression returns true if any of its arguments is true (i.e. if an argument error was logged).
+ *
+ * For example, log_badargs_if(x==NULL) will log "Invalid Argument (x==NULL)" and return true if x is NULL.
+ */
+#define log_badargs_if(c1) _flib_lbi(c1,#c1)
+#define log_badargs_if2(c1, c2) _flib_lbi2(c1,#c1,c2,#c2)
+#define log_badargs_if3(c1, c2, c3) _flib_lbi3(c1,#c1,c2,#c2,c3,#c3)
+#define log_badargs_if4(c1, c2, c3, c4) _flib_lbi4(c1,#c1,c2,#c2,c3,#c3,c4,#c4)
+#define log_badargs_if5(c1, c2, c3, c4, c5) _flib_lbi5(c1,#c1,c2,#c2,c3,#c3,c4,#c4,c5,#c5)
+#define log_badargs_if6(c1, c2, c3, c4, c5, c6) _flib_lbi6(c1,#c1,c2,#c2,c3,#c3,c4,#c4,c5,#c5,c6,#c6)
+
+#define log_oom_if(cond) log_e_if(cond, "Out of Memory")
+
+#define flib_log_e(...) _flib_flog(__func__, FLIB_LOGLEVEL_ERROR, __VA_ARGS__)
+#define flib_log_w(...) _flib_flog(__func__, FLIB_LOGLEVEL_WARNING, __VA_ARGS__)
+#define flib_log_i(...) _flib_flog(__func__, FLIB_LOGLEVEL_INFO, __VA_ARGS__)
+#define flib_log_d(...) _flib_flog(__func__, FLIB_LOGLEVEL_DEBUG, __VA_ARGS__)
+
+bool _flib_fassert(const char *func, int level, bool cond, const char *fmt, ...);
+void _flib_flog(const char *func, int level, const char *fmt, ...);
+
+/**
+ * Only log messages that are at least the indicated level
+ */
+void flib_log_setLevel(int level);
+int flib_log_getLevel();
+
+/**
+ * Log to the indicated file. You can pass NULL to log to stdout.
+ * This overrides setCallback and vice versa.
+ */
+void flib_log_setFile(FILE *logfile);
+
+/**
+ * Returns whether messages of this level are logged at the moment.
+ */
+bool flib_log_isActive(int level);
+
+/**
+ * Allows logging through an arbitrary callback function. Useful for integrating into an
+ * existing logging system. This overrides setFile and vice versa.
+ */
+void flib_log_setCallback(void (*logCallback)(int level, const char *msg));
+
+#endif /* LOGGING_H_ */
diff --git a/project_files/frontlib/util/util.c b/project_files/frontlib/util/util.c
new file mode 100644
index 0000000..ec87e1f
--- /dev/null
+++ b/project_files/frontlib/util/util.c
@@ -0,0 +1,212 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "util.h"
+#include "logging.h"
+
+#include <stddef.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <limits.h>
+
+char *flib_asprintf(const char *fmt, ...) {
+	va_list argp;
+	va_start(argp, fmt);
+	char *result = flib_vasprintf(fmt, argp);
+	va_end(argp);
+	return result;
+}
+
+char *flib_vasprintf(const char *fmt, va_list args) {
+	char *result = NULL;
+	if(!log_badargs_if(fmt==NULL)) {
+		int requiredSize = vsnprintf(NULL, 0, fmt, args)+1;					// Figure out how much memory we need,
+		if(!log_e_if(requiredSize<0, "Error formatting string with template \"%s\"", fmt)) {
+			char *tmpbuf = flib_malloc(requiredSize);						// allocate it
+			if(tmpbuf && vsnprintf(tmpbuf, requiredSize, fmt, args)>=0) {	// and then do the actual formatting.
+				result = tmpbuf;
+				tmpbuf = NULL;
+			}
+			free(tmpbuf);
+		}
+	}
+	return result;
+}
+
+char *flib_join(char **parts, int partCount, const char *delimiter) {
+	char *result = NULL;
+	if(!log_badargs_if2(parts==NULL, delimiter==NULL)) {
+		size_t totalSize = 1;
+		size_t delimLen = strlen(delimiter);
+		for(int i=0; i<partCount; i++) {
+			totalSize += strlen(parts[i]) + delimLen;
+		}
+		result = flib_malloc(totalSize);
+
+		if(result) {
+			size_t outpos = 0;
+			for(int i=0; i<partCount; i++) {
+				if(i>0) {
+					strcpy(result+outpos, delimiter);
+					outpos += delimLen;
+				}
+				strcpy(result+outpos, parts[i]);
+				outpos += strlen(parts[i]);
+			}
+		}
+	}
+	return result;
+}
+
+char *flib_strdupnull(const char *str) {
+	return str==NULL ? NULL : flib_asprintf("%s", str);
+}
+
+void *flib_bufdupnull(const void *buf, size_t size) {
+	void *result = NULL;
+	if(!log_badargs_if(buf==NULL && size>0)) {
+		result = flib_malloc(size);
+		if(result) {
+			memcpy(result, buf, size);
+		}
+	}
+	return result;
+}
+
+void *flib_malloc(size_t size) {
+	void *result = malloc(size);
+	if(!result && size>0) {
+		flib_log_e("Out of memory trying to malloc %zu bytes.", size);
+	}
+	return result;
+}
+
+void *flib_calloc(size_t count, size_t elementsize) {
+	void *result = calloc(count, elementsize);
+	if(!result && count>0 && elementsize>0) {
+		flib_log_e("Out of memory trying to calloc %zu objects of %zu bytes each.", count, elementsize);
+	}
+	return result;
+}
+
+void *flib_realloc(void *ptr, size_t size) {
+	void *result = realloc(ptr, size);
+	if(!result && size>0) {
+		flib_log_e("Out of memory trying to realloc %zu bytes.", size);
+	}
+	return result;
+}
+
+static bool isAsciiAlnum(char c) {
+	return (c>='0' && c<='9') || (c>='a' && c <='z') || (c>='A' && c <='Z');
+}
+
+char *flib_urlencode(const char *inbuf) {
+	return flib_urlencode_pred(inbuf, isAsciiAlnum);
+}
+
+static size_t countCharsToEscape(const char *inbuf, bool (*needsEscaping)(char c)) {
+	size_t result = 0;
+	for(const char *c=inbuf; *c; c++) {
+		if(needsEscaping(*c)) {
+			result++;
+		}
+	}
+	return result;
+}
+
+char *flib_urlencode_pred(const char *inbuf, bool (*needsEscaping)(char c)) {
+	char *result = NULL;
+	if(inbuf && !log_badargs_if(needsEscaping == NULL)) {
+		size_t insize = strlen(inbuf);
+		if(!log_e_if(insize > SIZE_MAX/4, "String too long: %zu bytes.", insize)) {
+			size_t escapeCount = countCharsToEscape(inbuf, needsEscaping);
+			result = flib_malloc(insize + escapeCount*2 + 1);
+		}
+		if(result) {
+			char *out = result;
+			for(const char *in = inbuf; *in; in++) {
+				if(!needsEscaping(*in)) {
+					*out = *in;
+					out++;
+				} else {
+					snprintf(out, 4, "%%%02x", (unsigned)(*(uint8_t*)in));
+					out += 3;
+				}
+			}
+			*out = 0;
+		}
+	}
+	return result;
+}
+
+char *flib_urldecode(const char *inbuf) {
+	if(!inbuf) {
+		return NULL;
+	}
+	char *outbuf = flib_malloc(strlen(inbuf)+1);
+	if(!outbuf) {
+		return NULL;
+	}
+
+    size_t inpos = 0, outpos = 0;
+    while(inbuf[inpos]) {
+        if(inbuf[inpos] == '%' && isxdigit(inbuf[inpos+1]) && isxdigit(inbuf[inpos+2])) {
+            char temp[3] = {inbuf[inpos+1],inbuf[inpos+2],0};
+            outbuf[outpos++] = strtol(temp, NULL, 16);
+            inpos += 3;
+        } else {
+        	outbuf[outpos++] = inbuf[inpos++];
+        }
+    }
+    outbuf[outpos] = 0;
+    char *shrunk = realloc(outbuf, outpos+1);
+    return shrunk ? shrunk : outbuf;
+}
+
+bool flib_contains_dir_separator(const char *str) {
+	if(!log_badargs_if(!str)) {
+		for(;*str;str++) {
+			if(*str=='\\' || *str=='/') {
+				return true;
+			}
+		}
+	}
+	return false;
+}
+
+bool flib_strempty(const char *str) {
+	return !str || !*str;
+}
+
+int flib_gets(char *str, size_t strlen) {
+	if(fgets(str, strlen, stdin)) {
+		for(char *s=str; *s; s++) {
+			if(*s=='\r' || *s=='\n') {
+				*s = 0;
+				break;
+			}
+		}
+		return 0;
+	}
+	return -1;
+}
diff --git a/project_files/frontlib/util/util.h b/project_files/frontlib/util/util.h
new file mode 100644
index 0000000..6d3dba2
--- /dev/null
+++ b/project_files/frontlib/util/util.h
@@ -0,0 +1,122 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef FLIB_UTIL_H_
+#define FLIB_UTIL_H_
+
+#include <stddef.h>
+#include <stdarg.h>
+#include <stdbool.h>
+
+/**
+ * Prints a format string to a newly allocated buffer of the required size.
+ * Parameters are like those for printf. Returns NULL on error.
+ *
+ * Returned buffer must be free()d
+ */
+char *flib_asprintf(const char *fmt, ...);
+
+/**
+ * Exactly as flib_asprintf, but accepts a va_list.
+ */
+char *flib_vasprintf(const char *fmt, va_list args);
+
+/**
+ * Creates a new string (that must be freed) containing all parts
+ * joined together, with the specified delimiter between each.
+ */
+char *flib_join(char **parts, int partCount, const char *delimiter);
+
+/**
+ * Return a duplicate of the provided string, or NULL if an error
+ * occurs or if str is already NULL.
+ *
+ * Returned buffer must be free()d
+ */
+char *flib_strdupnull(const char *str);
+
+/**
+ * Return a duplicate of the provided buffer, or NULL if an error
+ * occurs or if buf is already NULL or if size is 0.
+ *
+ * Returned buffer must be free()d
+ */
+void *flib_bufdupnull(const void *buf, size_t size);
+
+/**
+ * Simple malloc wrapper that automatically logs an error if no memory
+ * is available. Otherwise behaves exactly like malloc.
+ */
+void *flib_malloc(size_t size);
+
+/**
+ * Simple calloc wrapper that automatically logs an error if no memory
+ * is available. Otherwise behaves exactly like calloc.
+ */
+void *flib_calloc(size_t count, size_t elementsize);
+
+/**
+ * Simple realloc wrapper that automatically logs an error if no memory
+ * is available. Otherwise behaves exactly like realloc.
+ */
+void *flib_realloc(void *ptr, size_t size);
+
+/**
+ * Replace all non-alphanumeric and non-ascii bytes with escape
+ * sequences in the form %XX. Does not modify the original string,
+ * but returns a newly allocated one that must be free()d. Returns
+ * null on failure or if null was passed as argument.
+ *
+ * This should work fine with all ASCII-based charsets including UTF-8.
+ */
+char *flib_urlencode(const char *str);
+
+/**
+ * Replace some bytes with escape sequences in the form %XX.
+ * Does not modify the original string, but returns a newly allocated
+ * one that must be free()d.
+ *
+ * All bytes for which the predicate function returns true are escaped.
+ *
+ * Returns null on failure or if null was passed as argument.
+ */
+char *flib_urlencode_pred(const char *str, bool (*needsEscaping)(char c));
+
+/**
+ * Replace escape sequences of the form %XX with their byte values.
+ * Does not modify the original string, but returns a newly allocated
+ * one that must be free()d. Returns null on failure or if null was
+ * passed as argument.
+ */
+char *flib_urldecode(const char *str);
+
+/**
+ * Figure out if the string contains / or \. Useful in routines that
+ * construct filenames.
+ */
+bool flib_contains_dir_separator(const char *str);
+
+/**
+ * Returns true if str is either NULL or points to a 0-length string
+ */
+bool flib_strempty(const char *str);
+
+int flib_gets(char *str, size_t strlen);
+
+#endif
diff --git a/share/hedgewars/Data/Locale/de.txt b/share/hedgewars/Data/Locale/de.txt
index 4ff1118..99130f3 100644
--- a/share/hedgewars/Data/Locale/de.txt
+++ b/share/hedgewars/Data/Locale/de.txt
@@ -120,22 +120,22 @@
 02:00=Schlecht, schlecht, %1 …
 02:00=%1 sollte lieber WarMUX spielen
 02:00=%1 hat versucht, die Kugeln mit den Zähnen zu fangen
-02:00=%1 findet seinen Platz in der Walhall
+02:00=%1 findet einen Platz in der Walhall
 02:00=%1 geht den Weg der Dinosaurier
 02:00=%1 bringt die Igelspezies einen Schritt näher zum Aussterben
 02:00=%1 wird vermisst werden
 02:00=%1 ist ab jetzt ein Ex-Igel
 02:00=%1 sieht sich die Radieschen von unten an
-02:00=%1 hat aufgehört, zu sein
+02:00=%1 hat aufgehört zu existieren
 02:00=Verabschieden Sie sich von %1
 02:00=Für %1 gibt es keine Hoffnung mehr
 02:00=%1 trat von der Lebensbühne ab
 02:00=%1 erleidet ein spontanes multiples Organversagen
 02:00=%1 ist mausetot
-02:00=%1s Lebensuhr ist abgelaufen
+02:00=Für %1 ist die Lebensuhr abgelaufen
 02:00=Beraubt des Lebens, ruht %1 in Frieden
 02:00=%1 hatte eine geringe Schadenstoleranz
-02:00=%1 hat all seine Extraleben aufgebraucht
+02:00=%1 hat alle Extraleben aufgebraucht
 02:00=Ist ein Arzt im Haus?!
 02:00=%1 ist tot
 02:00=%1 ist hinüber
@@ -143,6 +143,13 @@
 02:00=Schade um %1
 02:00=Wir trauern um %1
 02:00=%1 beißt ins Gras
+02:00=%1 ist jetzt im Igel-Himmel
+02:00=%1 spielt nicht mehr mit
+02:00=%1 ist ausgeschieden
+02:00=Hat %1 eigentlich ein Testament gemacht?
+02:00=%1 spürt keinen Schmerz mehr
+02:00=%1 muss nicht mehr leiden
+02:00=%1 hat eine Abkürzung gefunden …
 
 ; Hog (%1) drowned
 02:01=%1 geht auf Tauchstation!
@@ -163,30 +170,29 @@
 02:01=%1 geht unter die Perlentaucher!
 02:01=%1 über Bord!
 02:01=%1 verlässt das sinkende Schiff
-02:01=%1 überschätzt seinen Auftrieb!
+02:01=%1 überschätzt den eigenen Auftrieb!
 02:01=%1 erliegt dem Sog der Tiefe!
 02:01=%1 geht der Sache auf den Grund!
 02:01=%1 wäre fast verdurstet!
 02:01=%1 macht »Gluck, gluck, gluck!«
 02:01=%1 macht »Platsch!«
-02:01=%1 vergaß seine Schwimmflügel
+02:01=%1 hätte die Schwimmflügel diesmal nicht zu Hause lassen sollen
 02:01=%1 hätte Schwimmunterricht nehmen sollen
-02:01=%1 ließ sein Surfbrett zu Hause
+02:01=%1 ließ das Surfbrett zu Hause
 02:01=%1 wird gewaschen
 02:01=%1 ist ein nasser Igel
-02:01=%1 hat seine Schwimmweste vergessen
+02:01=%1 hat die Schwimmweste vergessen
 02:01=%1 macht »Plitsch-platsch!«
 02:01=%1 sieht durstig aus
 02:01=%1 ist auf dem Meer verschollen
 02:01=%1 bekommt eine Seebestattung
-02:01=%1 übt sein Rückenschwimmen
-02:01=%1 geht auf der Suche nach der Titanic
+02:01=%1 übt Rückenschwimmen
 02:01=%1 ist nicht Jesus
 02:01=%1 hat ein Leck
 02:01=Wie viele Igel wohl da unten liegen?
 02:01=%1 macht das Meer etwas höher
 02:01=%1 ist absolut nicht Marinetauglich
-02:01=%1 glaubt, er sei ein Fisch
+02:01=%1 hält sich für einen Fisch
 02:01=Wenigstens ging die Sache nicht ins Klo, %1!
 02:01=Sonic konnte nicht schwimmen, %1 auch nicht
 02:01=%1 spielt »Flipper der Delphin«
@@ -203,6 +209,15 @@
 02:01=%1, Igel, der mit dem Blubb
 02:01=Nächster Halt: Meeresgrund
 02:01=%1 hätte den Schwimmkurs nicht schwänzen sollen
+02:01=Fischers Fritze fischt frische ... Igel?!
+02:01=Grüß die Fische von uns, %1!
+02:01=%1 erkundet das Meer
+02:01=%1 folgt dem Ruf der Meere
+02:01=%1 ist jetzt ein Seeigel!
+02:01=Igel haben keine Kiemen, %1!
+02:01=%1 lässt sich diese  einmalige  Tauchgelegenheit nicht entgehen
+02:01=Und wir dachten %1 könnte nicht noch tiefer sinken …
+02:01=%1 zieht eine Etage tiefer
 
 ; Round starts
 02:02=Auf in die Schlacht!
@@ -272,6 +287,8 @@
 02:05=Vorräte!
 02:05=Ein Erste-Hilfe-Koffer!
 02:05=Ein Grund zur Hoffnung!
+02:05=Frisch aus dem Jungbrunnen
+02:05=Lebenszeit in Kisten
 
 ; New ammo crate
 02:06=Nachschub!
@@ -295,6 +312,10 @@
 02:06=Lassen Sie nicht zu, dass sich der Feind sie holt!
 02:06=Schönes neues Spielzeug!
 02:06=Eine geheimnisvolle Kiste!
+02:06=Ein eckiges Ü-Ei!
+02:06=Die Holzkiste der Pandora!
+02:06=Willst du mit mir spielen?
+02:06=Quadratisch, praktisch, … gefährlich?
 
 ; New utility crate
 02:07=Nützliches?
@@ -307,6 +328,7 @@
 02:07=Dies sollte gut sein!
 02:07=Verwenden Sie diese mit Bedacht
 02:07=Uff, diese Box ist schwer
+02:07=Futter für Strategen
 
 ; Hog (%1) skips his turn
 02:08=%1 ist so ein Langeweiler …
@@ -346,6 +368,15 @@
 02:08=%1 hat sich fast zu Tode erschrocken
 02:08=%1 ist eingeschlafen
 02:08=%1 ist wohl nur aus Versehen hier
+02:08=%1 steckt den Kopf in den Sand
+02:08=%1 spielt lieber Skat
+02:08=%1 guckt zu
+02:08=%1 vertraut auf das Karma
+02:08=%1 igelt sich ein
+02:08=%1 zählt Schäfchen
+02:08=%1 lässt sich die Sonne auf den Bauch scheinen
+02:08=%1 genießt die Stille
+02:08=%1 fragt sich ob es schon Zeit für den Winterschlaf ist
 
 ; Hog (%1) hurts himself only
 02:09=%1 sollte lieber zielen üben!
@@ -355,20 +386,17 @@
 02:09=%1 hat keinen Selbsterhaltungstrieb
 02:09=%1 ist durcheinander
 02:09=%1 vermasselt’s
-02:09=Das war ein schlechter Schuss, %1
+02:09=Das hat wohl nicht ganz geklappt, %1
 02:09=%1 geht ein wenig zu sorglos mit gefährlichen Waffen um
 02:09=%1 sollte eine Änderung der Laufbahn betrachten
-02:09=Das. War. Schlecht!
 02:09=Nein, nein, nein, %1, Sie müssen auf den Feind schießen!
 02:09=%1 bewegt sich einen Schritt näher zum Selbstmord
 02:09=%1, Helfer des Feindes
-02:09=Das war dumm, %1
+02:09=%1 hatte das anders geplant
 02:09=%1 lebt nach dem Mantra des »Ohne Schmerz kein Sieg!«
 02:09=%1 ist verwirrt
-02:09=%1 ist geistig verwirrt
 02:09=%1 verletzt sich selbst
 02:09=%1 blamiert sich!
-02:09=%1 ist ein Trottel!
 02:09=%1 ist ungeschickt
 02:09=%1 zeigt dem Feind, wozu er fähig ist
 02:09=%1 ist nicht perfekt
@@ -378,8 +406,15 @@
 02:09=Wie peinlich!
 02:09=Ich hoffe, dass das niemand gesehen hat, %1
 02:09=%1 sollte dringend die Gebrauchsanweisung noch einmal durchlesen
-02:09=%1s hat eindeutig versagt
 02:09=%1s Schuss ging nach hinten los!
+02:09=%1 macht sich mit den Waffen vertraut
+02:09=%1 schießt ein Eigentor
+02:09=%1 kennt keinen Schmerz
+02:09=%1 mag Bumerangs und Jo-Jos
+02:09=Wer Anderen eine Grube gräbt …
+02:09=%1 wird vom Pech verfolgt
+02:09=Auch %1 macht mal Fehler
+02:09=Hoppla?!
 
 ; Hog (%1) shot an home run (using the bat and another hog)
 02:10=Home Run!
@@ -389,6 +424,10 @@
 02:10=%1 vor, noch ein Tor!
 02:10=Ausgezeichnet, %1!
 02:10=Bravo, %1!
+02:10=Sehr sportlich, %1!
+02:10=Flieg, Iglein, flieg!
+02:10=%1 lässt Igel fliegen
+02:10=%1 ist Physikstudent
 
 ; Hog (%1) has to leave (team is gone)
 02:11=%1 muss ins Bett!
@@ -406,6 +445,10 @@
 02:11=%1 verschwindet
 02:11=%1 ist futsch
 02:11=%1 hat wohl besseres zu tun
+02:11=%1 löst sich in Luft auf
+02:11=%1 bringt den Müll raus
+02:11=%1 flieht
+02:11=%1 braucht Urlaub
 
 ; Weapon Categories
 03:00=Zeitzünder-Granate
diff --git a/share/hedgewars/Data/Locale/hedgewars_de.ts b/share/hedgewars/Data/Locale/hedgewars_de.ts
index 3d4e05f..74c8415 100644
--- a/share/hedgewars/Data/Locale/hedgewars_de.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_de.ts
@@ -939,7 +939,7 @@ just enter your nickname.</source>
     </message>
     <message>
         <source>Play a game across a network</source>
-        <translation>Spiele über ein Netwerk</translation>
+        <translation>Spiele über ein Netzwerk</translation>
     </message>
     <message>
         <source>Read about who is behind the Hedgewars Project</source>
@@ -2154,7 +2154,7 @@ Bitte überprüfe deine Installation!</translation>
     </message>
     <message>
         <source>Netgame - Error</source>
-        <translation>Netwerkspiel - Fehler</translation>
+        <translation>Netzwerkspiel - Fehler</translation>
     </message>
     <message>
         <source>Please select a server from the list</source>
diff --git a/share/hedgewars/Data/Locale/hedgewars_pt_PT.ts b/share/hedgewars/Data/Locale/hedgewars_pt_PT.ts
index 2f9eb52..72b623e 100644
--- a/share/hedgewars/Data/Locale/hedgewars_pt_PT.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_pt_PT.ts
@@ -100,19 +100,19 @@
     </message>
     <message>
         <source>We are always happy about suggestions, ideas, or bug reports.</source>
-        <translation type="unfinished"></translation>
+        <translation>Estamos sempre abertos a novas sugestões, ideias, ou submissões de bugs encontrados.</translation>
     </message>
     <message>
         <source>Send us feedback!</source>
-        <translation type="unfinished"></translation>
+        <translation>Envia-nos feedback!</translation>
     </message>
     <message>
         <source>If you found a bug, you can see if it's already been reported here: </source>
-        <translation type="unfinished"></translation>
+        <translation>Se encontraste um bug, podes verificar se já foi submetido aqui: </translation>
     </message>
     <message>
         <source>Your email address is optional, but necessary if you want us to get back at you.</source>
-        <translation type="unfinished"></translation>
+        <translation>O teu e-mail é opcional, mas necessário se quiseres que te contactemos de volta.</translation>
     </message>
 </context>
 <context>
@@ -195,18 +195,18 @@
     </message>
     <message>
         <source>Scheme '%1' not supported</source>
-        <translation type="unfinished"></translation>
+        <translation>Esquema '%1' não suportado</translation>
     </message>
     <message>
         <source>Cannot create directory %1</source>
-        <translation type="unfinished">Não foi possível criar o diretório %1</translation>
+        <translation>Não foi possível criar o diretório %1</translation>
     </message>
     <message>
         <source>Failed to open data directory:
 %1
 
 Please check your installation!</source>
-        <translation type="unfinished">Erro ao abrir o diretório:
+        <translation>Erro ao abrir o diretório:
 %1
 
 Por favor verifica a tua instalação!</translation>
@@ -263,15 +263,15 @@ Por favor verifica a tua instalação!</translation>
     </message>
     <message>
         <source>%1 has joined</source>
-        <translation type="unfinished"></translation>
+        <translation>%1 entrou</translation>
     </message>
     <message>
         <source>%1 has left</source>
-        <translation type="unfinished"></translation>
+        <translation>%1 saíu</translation>
     </message>
     <message>
         <source>%1 has left (%2)</source>
-        <translation type="unfinished"></translation>
+        <translation>%1 saíu (%2)</translation>
     </message>
 </context>
 <context>
@@ -384,7 +384,7 @@ Por favor, aguarda alguns segundos e tenta novamente.</translation>
     </message>
     <message>
         <source>This page requires an internet connection.</source>
-        <translation type="unfinished"></translation>
+        <translation>Esta página requer ligação à internet</translation>
     </message>
 </context>
 <context>
@@ -526,7 +526,7 @@ Por favor, aguarda alguns segundos e tenta novamente.</translation>
     </message>
     <message>
         <source>Theme: %1</source>
-        <translation type="unfinished"></translation>
+        <translation>Tema: %1</translation>
     </message>
 </context>
 <context>
@@ -606,15 +606,18 @@ Por favor, aguarda alguns segundos e tenta novamente.</translation>
 
 If you don't have an account on www.hedgewars.org,
 just enter your nickname.</source>
-        <translation type="unfinished"></translation>
+        <translation>Por favor faz login para aceder ao servidor.
+		
+Se ainda não tens uma conta em www.hedgewars.org,
+simplesmente insere o teu nome de utilizador.</translation>
     </message>
     <message>
         <source>Nickname:</source>
-        <translation type="unfinished"></translation>
+        <translation>Utilizador:</translation>
     </message>
     <message>
         <source>Password:</source>
-        <translation type="unfinished"></translation>
+        <translation>Password:</translation>
     </message>
 </context>
 <context>
@@ -770,11 +773,11 @@ just enter your nickname.</source>
     <name>PageDataDownload</name>
     <message>
         <source>Loading, please wait.</source>
-        <translation type="unfinished"></translation>
+        <translation>A carregar, aguarda por favor.</translation>
     </message>
     <message>
         <source>This page requires an internet connection.</source>
-        <translation type="unfinished"></translation>
+        <translation>Esta página requer ligação à internet.</translation>
     </message>
 </context>
 <context>
@@ -921,11 +924,11 @@ just enter your nickname.</source>
     </message>
     <message>
         <source>Play again</source>
-        <translation type="unfinished"></translation>
+        <translation>Jogar novamente</translation>
     </message>
     <message>
         <source>Save</source>
-        <translation type="unfinished">Gravar</translation>
+        <translation>Gravar</translation>
     </message>
 </context>
 <context>
@@ -1035,11 +1038,11 @@ just enter your nickname.</source>
     <name>PageNetServer</name>
     <message>
         <source>Click here for details</source>
-        <translation type="unfinished"></translation>
+        <translation>Clica aqui para detalhes</translation>
     </message>
     <message>
         <source>Insert your address here</source>
-        <translation type="unfinished"></translation>
+        <translation>Insere aqui o teu endereço</translation>
     </message>
 </context>
 <context>
@@ -1996,7 +1999,7 @@ Deseja mesmo sair?</translation>
     </message>
     <message>
         <source>This setting will be effective at next restart.</source>
-        <translation type="unfinished"></translation>
+        <translation>Esta opção entrará em efeito quando o jogo for reiniciado.</translation>
     </message>
 </context>
 <context>
@@ -2385,23 +2388,23 @@ Nem todos os jogadores estão prontos.</translation>
     </message>
     <message>
         <source>Reset</source>
-        <translation type="unfinished"></translation>
+        <translation>Repor</translation>
     </message>
     <message>
         <source>Set the default server port for Hedgewars</source>
-        <translation type="unfinished"></translation>
+        <translation>Define a porta por omisão do servidor Hedgewars</translation>
     </message>
     <message>
         <source>Invite your friends to your server in just 1 click!</source>
-        <translation type="unfinished"></translation>
+        <translation>Convida os teus amigos para o teu servidor com apenas 1 click!</translation>
     </message>
     <message>
         <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
-        <translation type="unfinished"></translation>
+        <translation>Clica para copiar o URL do teu servidor. Partilha este link com os teus amigos para que se possam juntar a ti.</translation>
     </message>
     <message>
         <source>Start private server</source>
-        <translation type="unfinished"></translation>
+        <translation>Iniciar o servidor privado</translation>
     </message>
 </context>
 <context>
@@ -2516,19 +2519,20 @@ Nem todos os jogadores estão prontos.</translation>
     <name>TCPBase</name>
     <message>
         <source>Unable to start server at %1.</source>
-        <translation type="unfinished"></translation>
+        <translation>Não foi possível iniciar o servidor em %1.</translation>
     </message>
     <message>
         <source>Unable to run engine at %1
 Error code: %2</source>
-        <translation type="unfinished"></translation>
+        <translation>Não foi possível iniciar o motor de jogo em %1
+Código de erro:: %2</translation>
     </message>
 </context>
 <context>
     <name>TeamSelWidget</name>
     <message>
         <source>At least two teams are required to play!</source>
-        <translation type="unfinished"></translation>
+        <translation>São necessárias pelo menos 2 equipas (para jogar)!</translation>
     </message>
 </context>
 <context>
diff --git a/share/hedgewars/Data/Locale/missions_en.txt b/share/hedgewars/Data/Locale/missions_en.txt
index 478ef59..0d002b7 100644
--- a/share/hedgewars/Data/Locale/missions_en.txt
+++ b/share/hedgewars/Data/Locale/missions_en.txt
@@ -49,5 +49,5 @@ User_Mission_-_Nobody_Laugh.desc="This ain't no joke."
 User_Mission_-_RCPlane_Challenge.name=Challenge: RC Plane
 User_Mission_-_RCPlane_Challenge.desc="Feeling pretty confident, eh, flyboy?"
 
-portal.name= Mission: Portal training mission
+portal.name=Mission: Portal Mind Challenge
 portal.desc="Use the portal to move fast and far, use it to kill, use it with caution!"
diff --git a/share/hedgewars/Data/Locale/missions_fr.txt b/share/hedgewars/Data/Locale/missions_fr.txt
index 9b5a92d..bc3a22f 100644
--- a/share/hedgewars/Data/Locale/missions_fr.txt
+++ b/share/hedgewars/Data/Locale/missions_fr.txt
@@ -45,3 +45,6 @@ User_Mission_-_Rope_Knock_Challenge.desc="Regarde derrière toi !"
 
 User_Mission_-_RCPlane_Challenge.name=Challenge: Avion télécommandé
 User_Mission_-_RCPlane_Challenge.desc="Plutôt confiant, hein, aviateur ?"
+
+portal.name=Portal Casse Tête
+portal.desc="Utilisez le fusil à portail pour voyager loin et rapidemment ou pour tuer ! Utiliser avec prudence !"
diff --git a/share/hedgewars/Data/Locale/missions_pt.txt b/share/hedgewars/Data/Locale/missions_pt.txt
old mode 100755
new mode 100644
diff --git a/share/hedgewars/Data/Locale/missions_tr.txt b/share/hedgewars/Data/Locale/missions_tr.txt
old mode 100755
new mode 100644
diff --git a/share/hedgewars/Data/Locale/pt_PT.lua b/share/hedgewars/Data/Locale/pt_PT.lua
index 125f8c4..6297c8c 100644
--- a/share/hedgewars/Data/Locale/pt_PT.lua
+++ b/share/hedgewars/Data/Locale/pt_PT.lua
@@ -779,7 +779,7 @@ locale = {
 	["TIME: "] = "TEMPO: ",
 --      ["Tip: The rope physics are different than in the real world, |use it to your advantage!"] = "", -- Basic_Training_-_Rope
 	["Toggle Shield"] = "Ligar\Desligar Escudo",
---      ["To help you, of course!"] = "", -- A_Classic_Fairytale:journey
+	["To help you, of course!"] = "Para te ajudar claro!", -- A_Classic_Fairytale:journey
 --      ["To place a girder, select it, use [Left] and [Right] to select angle and length, place with [Left Click]"] = "", -- A_Classic_Fairytale:shadow
 --      ["Torn Muscle"] = "", -- A_Classic_Fairytale:journey
 --      [" to save the village."] = "", -- A_Classic_Fairytale:dragon
@@ -848,14 +848,14 @@ locale = {
 --      ["We have to unite and defeat those cylergs!"] = "Temos de nos unir e derrotar estes ciber-pernudos!", -- A_Classic_Fairytale:enemy
 	["Welcome, Leaks A Lot!"] = "Bem vindo, Leaks a Lot!", -- A_Classic_Fairytale:journey
 	["Well done."] = "Bom trabalho.",
---      ["We'll give you a problem then!"] = "", -- A_Classic_Fairytale:enemy
+	["We'll give you a problem then!"] = "Nós arranjamos-te um problema então!", -- A_Classic_Fairytale:enemy
 --      ["We'll spare your life for now!"] = "Vamos poupar a tua vida para ja!", -- A_Classic_Fairytale:backstab
 --      ["Well, that was a waste of time."] = "Bem, isto foi um desperdicio de tempo.", -- A_Classic_Fairytale:dragon
---      ["Well, well! Isn't that the cutest thing you've ever seen?"] = "", -- A_Classic_Fairytale:journey
---      ["Well, yes. This was a cyborg television show."] = "Bem, claro. Isto era um programa de televisão para cyborgs.", -- A_Classic_Fairytale:enemy
---      ["We made sure noone followed us!"] = "Certificamo-nos que ninguem nos seguiu!", -- A_Classic_Fairytale:backstab
---      ["We need to move!"] = "Temos de nos mover!", -- A_Classic_Fairytale:united
---      ["We need to prevent their arrival!"] = "Temos de prevenir que cheguem!", -- A_Classic_Fairytale:backstab
+--      ["Well, well! Isn't that the cutest thing you've ever seen?"] = "Bem, bem! Não isto é coisa mais fofa que já alguma vez viste?", -- A_Classic_Fairytale:journey
+	["Well, yes. This was a cyborg television show."] = "Bem, claro. Isto era um programa de televisão para cyborgs.", -- A_Classic_Fairytale:enemy
+	["We made sure noone followed us!"] = "Certificá-mo-nos que ninguém nos seguiu! que ninguem nos seguiu!", -- A_Classic_Fairytale:backstab
+	["We need to move!"] = "Temos de ir!", -- A_Classic_Fairytale:united
+--      ["We need to prevent their arrival!"] = "Temos de prevenir a sua chegada!", -- A_Classic_Fairytale:backstab
 	["We need to warn the village."] = "Temos de avisar a aldeia.", -- A_Classic_Fairytale:shadow
 --      ["We should head back to the village now."] = "", -- A_Classic_Fairytale:shadow
 --      ["We were trying to save her and we got lost."] = "Estavamos a tentar salva-la e acabamos por nos perder.", -- A_Classic_Fairytale:family
@@ -863,18 +863,18 @@ locale = {
 --      ["What?! A cannibal? Here? There is no time to waste! Come, you are prepared."] = "O quê? Um canibal? Aqui? Não ha tempo a perder! Vem, estás preparado.", -- A_Classic_Fairytale:first_blood
 	["What a douche!"] = "Que otário!", -- A_Classic_Fairytale:enemy
 --      ["What am I gonna...eat, yo?"] = "", -- A_Classic_Fairytale:family
---      ["What are you doing at a distance so great, young one?"] = "O que estás a tão grande distancia, jovem?", -- A_Classic_Fairytale:first_blood
+--      ["What are you doing at a distance so great, young one?"] = "O que estás a fazer a tão grande distancia, jovem?", -- A_Classic_Fairytale:first_blood
 --      ["What are you doing? Let her go!"] = "Que estás a fazer? Larga-a!", -- A_Classic_Fairytale:journey
 	["What a ride!"] = "Que viagem!", -- A_Classic_Fairytale:shadow
 	["What a strange cave!"] = "Que caverna estranha!", -- A_Classic_Fairytale:dragon
---      ["What a strange feeling!"] = "", -- A_Classic_Fairytale:backstab
+--      ["What a strange feeling!"] = "Tenho um mau persentimento!", -- A_Classic_Fairytale:backstab
 	["What do my faulty eyes observe? A spy!"] = "O que vêm observam os meus defeituoso olhos? Um espião!", -- A_Classic_Fairytale:first_blood
 --      ["Whatever floats your boat..."] = "O que quer que seja que faz o teu barco flutuar... (preciso melhor expressão verdadeiramente portuguesa)", -- A_Classic_Fairytale:shadow
 	[" What !! For all of this struggle i just win some ... TIME o0"] = " O quê !! Por todo este esforço tudo o que ganho é ... TEMPO o0", -- portal
 --      ["What has "] = "Foi aquilo ", -- A_Classic_Fairytale:backstab
 	["What? Here? How did they find us?!"] = "O quê? Aqui? Como raio nos encontraram?!", -- A_Classic_Fairytale:backstab
 --      ["What is this place?"] = "O que é este sitio?\Que (raio de) sitio é este?", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy
---      ["What shall we do with the traitor?"] = "O que fazemos com o traidor?", -- A_Classic_Fairytale:backstab
+	["What shall we do with the traitor?"] = "O que fazemos com o traidor?", -- A_Classic_Fairytale:backstab
 --      ["WHAT?! You're the ones attacking us!"] = "O QUÊ?! Voces é que nos atacaram\estão a atacar!", -- A_Classic_Fairytale:enemy
 	["When?"] = "Quando?", -- A_Classic_Fairytale:enemy
 	["When I find it..."] = "Quando o encontrar...", -- A_Classic_Fairytale:dragon
diff --git a/share/hedgewars/Data/Locale/pt_PT.txt b/share/hedgewars/Data/Locale/pt_PT.txt
index b3ff646..5357489 100644
--- a/share/hedgewars/Data/Locale/pt_PT.txt
+++ b/share/hedgewars/Data/Locale/pt_PT.txt
@@ -78,7 +78,7 @@
 01:16=Pouco
 01:17=Normal
 01:18=Muito
-01:19=Excessivo
+01:19=Imenso
 01:20=Ressalto: %1
 01:21=Áudio Silenciado
 
diff --git a/share/hedgewars/Data/Locale/tr.lua b/share/hedgewars/Data/Locale/tr.lua
old mode 100755
new mode 100644
diff --git a/share/hedgewars/Data/Locale/tr.txt b/share/hedgewars/Data/Locale/tr.txt
old mode 100755
new mode 100644
diff --git a/share/hedgewars/Data/Maps/Basketball/map.lua b/share/hedgewars/Data/Maps/Basketball/map.lua
index 34d8930..7671120 100644
--- a/share/hedgewars/Data/Maps/Basketball/map.lua
+++ b/share/hedgewars/Data/Maps/Basketball/map.lua
@@ -1,6 +1,6 @@
 -- Hedgewars - Basketball for 2+ Players
 
-HedgewarsScriptLoad("Scripts/Locale.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
 
 local score = {[0] = 0, [1] = 0, [2] = 0, [3] = 0, [4] = 0, [5] = 0}
 
diff --git a/share/hedgewars/Data/Maps/CTF_Blizzard/map.lua b/share/hedgewars/Data/Maps/CTF_Blizzard/map.lua
index 3a2063d..7abdbdb 100644
--- a/share/hedgewars/Data/Maps/CTF_Blizzard/map.lua
+++ b/share/hedgewars/Data/Maps/CTF_Blizzard/map.lua
@@ -91,7 +91,7 @@
 -- add support for more players
 -- re-enable sudden death, but set water rise to 0
 
-HedgewarsScriptLoad("Scripts/Locale.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
 
 ---------------------------------------------------------------
 ----------lots of bad variables and things
diff --git a/share/hedgewars/Data/Maps/Control/map.lua b/share/hedgewars/Data/Maps/Control/map.lua
index b10b078..2fa6bb0 100644
--- a/share/hedgewars/Data/Maps/Control/map.lua
+++ b/share/hedgewars/Data/Maps/Control/map.lua
@@ -49,7 +49,7 @@
 --script begins
 -----------------
 
-HedgewarsScriptLoad("Scripts/Locale.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
 
 ---------------------------------------------------------------
 ----------lots of bad variables and things
diff --git a/share/hedgewars/Data/Maps/Knockball/map.lua b/share/hedgewars/Data/Maps/Knockball/map.lua
index 5cdba09..5ef852f 100644
--- a/share/hedgewars/Data/Maps/Knockball/map.lua
+++ b/share/hedgewars/Data/Maps/Knockball/map.lua
@@ -1,6 +1,6 @@
 -- Hedgewars - Knockball for 2+ Players
 
-HedgewarsScriptLoad("Scripts/Locale.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
 
 local score = {[0] = 0, [1] = 0, [2] = 0, [3] = 0, [4] = 0, [5] = 0}
 
diff --git a/share/hedgewars/Data/Maps/Octorama/map.cfg b/share/hedgewars/Data/Maps/Octorama/map.cfg
old mode 100755
new mode 100644
diff --git a/share/hedgewars/Data/Maps/TrophyRace/map.lua b/share/hedgewars/Data/Maps/TrophyRace/map.lua
index 798b2e5..518ed5c 100644
--- a/share/hedgewars/Data/Maps/TrophyRace/map.lua
+++ b/share/hedgewars/Data/Maps/TrophyRace/map.lua
@@ -1,6 +1,6 @@
 -- Hedgewars - Roperace for 2+ Players
 
-HedgewarsScriptLoad("Scripts/Locale.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
 
 -- store number of hedgehogs
 local numhhs = 0
diff --git a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/dragon.lua b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/dragon.lua
index 0590319..577060d 100644
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/dragon.lua	
+++ b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/dragon.lua	
@@ -402,7 +402,8 @@ function DoMissionFinished()
   if progress and progress<6 then
     SaveCampaignVar("Progress", "6")
   end
-  ParseCommand("teamgone " .. loc("011101001"))
+  RestoreHedge(cyborg)
+  DeleteGear(cyborg)
   TurnTimeLeft = 0
 end
 
@@ -421,8 +422,8 @@ function CheckGearDead(gear)
 end
 
 function EndMission()
-  ParseCommand("teamgone " .. loc("Natives"))
-  ParseCommand("teamgone " .. loc("011101001"))
+  RestoreHedge(cyborg)
+  DeleteGear(cyborg)
   TurnTimeLeft = 0
 end
 
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Capture_the_Flag.cfg b/share/hedgewars/Data/Scripts/Multiplayer/Capture_the_Flag.cfg
old mode 100755
new mode 100644
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Highlander.cfg b/share/hedgewars/Data/Scripts/Multiplayer/Highlander.cfg
old mode 100755
new mode 100644
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/No_Jumping.cfg b/share/hedgewars/Data/Scripts/Multiplayer/No_Jumping.cfg
old mode 100755
new mode 100644
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/The_Specialists.cfg b/share/hedgewars/Data/Scripts/Multiplayer/The_Specialists.cfg
old mode 100755
new mode 100644
diff --git a/share/hedgewars/Data/Themes/Hell/Clouds.png b/share/hedgewars/Data/Themes/Hell/Clouds.png
old mode 100755
new mode 100644
diff --git a/share/hedgewars/Data/misc/hedgewars-mimeinfo.xml b/share/hedgewars/Data/misc/hedgewars-mimeinfo.xml
old mode 100755
new mode 100644
diff --git a/share/hedgewars/Data/misc/hedgewars.desktop b/share/hedgewars/Data/misc/hedgewars.desktop
old mode 100755
new mode 100644
index 7878969..16c20b0
--- a/share/hedgewars/Data/misc/hedgewars.desktop
+++ b/share/hedgewars/Data/misc/hedgewars.desktop
@@ -1,7 +1,6 @@
 [Desktop Entry]
 Type=Application
 Version=1.0
-Encoding=UTF-8
 Name=Hedgewars
 GenericName=Fighting Hedgehogs
 GenericName[de]=Kämpfende Igel
diff --git a/share/hedgewars/Data/misc/hwengine.desktop.in b/share/hedgewars/Data/misc/hwengine.desktop.in
index 3a5e5f2..a9eeacf 100644
--- a/share/hedgewars/Data/misc/hwengine.desktop.in
+++ b/share/hedgewars/Data/misc/hwengine.desktop.in
@@ -1,7 +1,6 @@
 [Desktop Entry]
 Type=Application
 Version=1.0
-Encoding=UTF-8
 Name=Hedgewars Engine
 GenericName=Hedgewars engine, for playback of saves and demos
 GenericName[de]=Hedgewars engine, für die Wiedergabe von gespeicherten Spielen und Demos
diff --git a/share/version_info.txt b/share/version_info.txt
index a2028c1..730d159 100644
--- a/share/version_info.txt
+++ b/share/version_info.txt
@@ -1,3 +1,3 @@
-Hedgewars versioning information, do not modify
-rev 9057
-hash 1617149e01a4
+Hedgewars versioning information, do not modify
+rev 9088
+hash 41424fca0ef3
diff --git a/tools/build_windows.bat b/tools/build_windows.bat
old mode 100644
new mode 100755
index 18af9ac..f295b8e
--- a/tools/build_windows.bat
+++ b/tools/build_windows.bat
@@ -40,7 +40,8 @@ call %QTDIR%\qtenv2.bat
 
 echo Running cmake...
 set ERRORLEVEL=
-cmake . -G "MinGW Makefiles" -DCMAKE_PREFIX_PATH="%CD%\misc\winutils\" -DPNG_LIBRARY="%CD%\misc\winutils\bin\libpng13.dll" -DCMAKE_BUILD_TYPE="%BUILD_TYPE%"
+cmake . -G "MinGW Makefiles" -DPNG_LIBRARY="%CD%\misc\winutils\bin\libpng13.dll" -DCMAKE_BUILD_TYPE="%BUILD_TYPE%" -DCMAKE_PREFIX_PATH="%CD%\misc\winutils\\"
+:: prefix should be last
 
 if %ERRORLEVEL% NEQ 0 goto exitpoint
 
diff --git a/tools/cmake_uninstall.cmake b/tools/cmake_uninstall.cmake
deleted file mode 100644
index 4364c22..0000000
--- a/tools/cmake_uninstall.cmake
+++ /dev/null
@@ -1,22 +0,0 @@
-IF(NOT EXISTS "/usr/home/unC0Rr/Sources/Hedgewars/Hedgewars-Clone/tools/../install_manifest.txt")
-  MESSAGE(FATAL_ERROR "Cannot find install manifest: \"/usr/home/unC0Rr/Sources/Hedgewars/Hedgewars-Clone/tools/../install_manifest.txt\"")
-ENDIF(NOT EXISTS "/usr/home/unC0Rr/Sources/Hedgewars/Hedgewars-Clone/tools/../install_manifest.txt")
-
-FILE(READ "/usr/home/unC0Rr/Sources/Hedgewars/Hedgewars-Clone/tools/../install_manifest.txt" files)
-STRING(REGEX REPLACE "\n" ";" files "${files}")
-FOREACH(file ${files})
-  MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
-  IF(EXISTS "$ENV{DESTDIR}${file}")
-    EXEC_PROGRAM(
-      "/usr/local/bin/cmake" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
-      OUTPUT_VARIABLE rm_out
-      RETURN_VALUE rm_retval
-      )
-    IF(NOT "${rm_retval}" STREQUAL 0)
-      MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
-    ENDIF(NOT "${rm_retval}" STREQUAL 0)
-  ELSE(EXISTS "$ENV{DESTDIR}${file}")
-    MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
-  ENDIF(EXISTS "$ENV{DESTDIR}${file}")
-ENDFOREACH(file)
-
diff --git a/tools/docgen.sh b/tools/docgen.sh
new file mode 100644
index 0000000..81daaa9
--- /dev/null
+++ b/tools/docgen.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+
+if [ -d QTfrontend ]; then
+	cd QTfrontend
+else
+	if [ -d ../QTfrontend ]; then
+		cd ../QTfrontend
+	else
+		echo 'abort: Directory "QTfrontend" not found!' >&2
+		exit 1
+	fi
+fi
+
+if [ -z "$1" ]; then
+	OUTPUT_DIRECTORY="../doc/QTfrontend"
+else
+	OUTPUT_DIRECTORY="$1"
+fi
+
+echo "Creating documentation for Qt-Frontend in $OUTPUT_DIRECTORY ..."
+
+if [ $(which hg) ]; then
+
+branch=$(hg identify -b)
+rev=$(hg identify -rdefault -i)
+
+branchurl="<a href=http://code.google.com/p/hedgewars/source/list?name=${branch}>${branch}</a>"
+revurl="<a href=http://code.google.com/p/hedgewars/source/detail?r=${rev}>${rev}</a>"
+
+export PROJECT_NUMBER="${branchurl} as of ${revurl}"
+export OUTPUT_DIRECTORY
+
+fi
+
+doxygen
+exit $?
diff --git a/tools/drawMapTest/drawMapTest.pro b/tools/drawMapTest/drawMapTest.pro
deleted file mode 100644
index 0cda0fe..0000000
--- a/tools/drawMapTest/drawMapTest.pro
+++ /dev/null
@@ -1,15 +0,0 @@
-# -------------------------------------------------
-# Project created by QtCreator 2010-11-27T22:18:20
-# -------------------------------------------------
-TARGET = drawMapTest
-TEMPLATE = app
-SOURCES += main.cpp \
-    mainwindow.cpp \
-    drawmapscene.cpp \
-    qaspectratiolayout.cpp \
-    drawmapwidget.cpp
-HEADERS += mainwindow.h \
-    drawmapscene.h \
-    qaspectratiolayout.h \
-    drawmapwidget.h
-FORMS += mainwindow.ui
diff --git a/tools/drawMapTest/drawmapscene.cpp b/tools/drawMapTest/drawmapscene.cpp
deleted file mode 100644
index 320ea6e..0000000
--- a/tools/drawMapTest/drawmapscene.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-#include <QDebug>
-#include <QGraphicsSceneMouseEvent>
-#include <QGraphicsPathItem>
-#include <QtEndian>
-
-#include "drawmapscene.h"
-
-template <class T> T sqr(const T & x)
-{
-    return x*x;
-}
-
-DrawMapScene::DrawMapScene(QObject *parent) :
-    QGraphicsScene(parent),
-    m_pen(Qt::yellow),
-    m_brush(Qt::yellow)
-{
-    setSceneRect(0, 0, 4096, 2048);
-
-    QLinearGradient gradient(0, 0, 0, 2048);
-    gradient.setColorAt(0, QColor(60, 60, 155));
-    gradient.setColorAt(1, QColor(155, 155, 60));
-    setBackgroundBrush(QBrush(gradient));
-
-    m_pen.setWidth(67);
-    m_pen.setJoinStyle(Qt::RoundJoin);
-    m_pen.setCapStyle(Qt::RoundCap);
-    m_currPath = 0;
-}
-
-void DrawMapScene::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent)
-{
-
-    qDebug() << "move" << mouseEvent->scenePos();
-
-    if(m_currPath && (mouseEvent->buttons() & Qt::LeftButton))
-    {
-        QPainterPath path = m_currPath->path();
-        path.lineTo(mouseEvent->scenePos());
-        paths.first().append(mouseEvent->scenePos().toPoint());
-        m_currPath->setPath(path);
-
-        emit pathChanged();
-    }
-}
-
-void DrawMapScene::mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent)
-{
-    qDebug() << "press" << mouseEvent->scenePos();
-
-    m_currPath = addPath(QPainterPath(), m_pen);
-
-    QPainterPath path = m_currPath->path();
-    QPointF p = mouseEvent->scenePos();
-    p += QPointF(0.01, 0.01);
-    path.moveTo(p);
-    path.lineTo(mouseEvent->scenePos());
-    paths.prepend(QList<QPoint>() << mouseEvent->scenePos().toPoint());
-    m_currPath->setPath(path);
-
-    emit pathChanged();
-}
-
-void DrawMapScene::mouseReleaseEvent(QGraphicsSceneMouseEvent * mouseEvent)
-{
-    qDebug() << "release" << mouseEvent->scenePos();
-
-    simplifyLast();
-
-    m_currPath = 0;
-}
-
-void DrawMapScene::undo()
-{
-    if(items().size())
-    {
-        removeItem(items().first());
-        paths.removeFirst();
-
-        emit pathChanged();
-    }
-}
-
-QByteArray DrawMapScene::encode()
-{
-    QByteArray b;
-
-    foreach(QList<QPoint> points, paths)
-    {
-        int cnt = 0;
-        foreach(QPoint point, points)
-        {
-            qint16 px = qToBigEndian((qint16)point.x());
-            qint16 py = qToBigEndian((qint16)point.y());
-            quint8 flags = 2;
-            if(!cnt) flags |= 0x80;
-            b.append((const char *)&px, 2);
-            b.append((const char *)&py, 2);
-            b.append((const char *)&flags, 1);
-
-            ++cnt;
-        }
-
-    }
-
-    return b;
-}
-
-void DrawMapScene::decode(QByteArray data)
-{
-    clear();
-    paths.clear();
-
-    QList<QPoint> points;
-
-    while(data.size() >= 5)
-    {
-        qint16 px = qFromBigEndian(*(qint16 *)data.data());
-        data.remove(0, 2);
-        qint16 py = qFromBigEndian(*(qint16 *)data.data());
-        data.remove(0, 2);
-        quint8 flags = *(quint8 *)data.data();
-        data.remove(0, 1);
-
-        //last chunk or first point
-        if((data.size() < 5) || (flags & 0x80))
-        {
-            if(points.size())
-            {
-                qDebug() << points;
-                addPath(pointsToPath(points), m_pen);
-                paths.prepend(points);
-
-                points.clear();
-            }
-        }
-
-        points.append(QPoint(px, py));
-    }
-}
-
-void DrawMapScene::simplifyLast()
-{
-    QList<QPoint> points = paths[0];
-
-    QPoint prevPoint = points.first();
-    int i = 1;
-    while(i < points.size())
-    {
-        if( (i != points.size() - 1)
-            && (sqr(prevPoint.x() - points[i].x()) + sqr(prevPoint.y() - points[i].y()) < 1000)
-          )
-            points.removeAt(i);
-        else
-        {
-            prevPoint = points[i];
-            ++i;
-        }
-    }
-
-    paths[0] = points;
-
-
-    // redraw path
-    {
-        QGraphicsPathItem * pathItem = static_cast<QGraphicsPathItem *>(items()[0]);
-        pathItem->setPath(pointsToPath(paths[0]));
-    }
-
-    emit pathChanged();
-}
-
-QPainterPath DrawMapScene::pointsToPath(const QList<QPoint> points)
-{
-    QPainterPath path;
-
-    if(points.size())
-    {
-        QPointF p = points[0] + QPointF(0.01, 0.01);
-        path.moveTo(p);
-
-        foreach(QPoint p, points)
-            path.lineTo(p);
-    }
-
-    return path;
-}
diff --git a/tools/drawMapTest/drawmapscene.h b/tools/drawMapTest/drawmapscene.h
deleted file mode 100644
index 436ba70..0000000
--- a/tools/drawMapTest/drawmapscene.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef DRAWMAPSCENE_H
-#define DRAWMAPSCENE_H
-
-#include <QGraphicsScene>
-#include <QPainterPath>
-
-class QGraphicsPathItem;
-
-typedef QList<QList<QPoint> > Paths;
-
-class DrawMapScene : public QGraphicsScene
-{
-Q_OBJECT
-public:
-    explicit DrawMapScene(QObject *parent = 0);
-
-    QByteArray encode();
-    void decode(QByteArray data);
-
-signals:
-    void pathChanged();
-
-public slots:
-    void undo();
-    void simplifyLast();
-
-private:
-    QPen m_pen;
-    QBrush m_brush;
-    QGraphicsPathItem  * m_currPath;
-    Paths paths;
-
-    virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent);
-    virtual void mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent);
-    virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent * mouseEvent);
-
-    QPainterPath pointsToPath(const QList<QPoint> points);
-};
-
-#endif // DRAWMAPSCENE_H
diff --git a/tools/drawMapTest/drawmapwidget.cpp b/tools/drawMapTest/drawmapwidget.cpp
deleted file mode 100644
index 6330169..0000000
--- a/tools/drawMapTest/drawmapwidget.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-#include "drawmapwidget.h"
-
-DrawMapWidget::DrawMapWidget(QWidget *parent) :
-    QWidget(parent),
-    ui(new Ui::DrawMapWidget)
-{
-    ui->setupUi(this);
-}
-
-DrawMapWidget::~DrawMapWidget()
-{
-    delete ui;
-}
-
-void DrawMapWidget::changeEvent(QEvent *e)
-{
-    QWidget::changeEvent(e);
-    switch (e->type()) {
-    case QEvent::LanguageChange:
-        ui->retranslateUi(this);
-        break;
-    default:
-        break;
-    }
-}
-
-void DrawMapWidget::setScene(DrawMapScene * scene)
-{
-    ui->graphicsView->setScene(scene);
-}
-
-void DrawMapWidget::resizeEvent(QResizeEvent * event)
-{
-    Q_UNUSED(event);
-
-    if(ui->graphicsView && ui->graphicsView->scene())
-        ui->graphicsView->fitInView(ui->graphicsView->scene()->sceneRect(), Qt::KeepAspectRatio);
-}
diff --git a/tools/drawMapTest/drawmapwidget.h b/tools/drawMapTest/drawmapwidget.h
deleted file mode 100644
index 743dcd3..0000000
--- a/tools/drawMapTest/drawmapwidget.h
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef DRAWMAPWIDGET_H
-#define DRAWMAPWIDGET_H
-
-#include <QWidget>
-#include <QHBoxLayout>
-#include <QPushButton>
-#include <QGraphicsView>
-#include <QApplication>
-
-#include "qaspectratiolayout.h"
-#include "drawmapscene.h"
-
-namespace Ui {
-    class Ui_DrawMapWidget
-    {
-    public:
-        QGraphicsView *graphicsView;
-        QPushButton *pbUndo;
-
-        void setupUi(QWidget *drawMapWidget)
-        {
-            QAspectRatioLayout * arLayout = new QAspectRatioLayout(drawMapWidget);
-            arLayout->setMargin(0);
-
-            graphicsView = new QGraphicsView(drawMapWidget);
-            arLayout->addWidget(graphicsView);
-
-            retranslateUi(drawMapWidget);
-
-            QMetaObject::connectSlotsByName(drawMapWidget);
-        } // setupUi
-
-        void retranslateUi(QWidget *drawMapWidget)
-        {
-            Q_UNUSED(drawMapWidget);
-        } // retranslateUi
-
-    };
-
-    class DrawMapWidget: public Ui_DrawMapWidget {};
-}
-
-class DrawMapWidget : public QWidget
-{
-    Q_OBJECT
-
-public:
-    explicit DrawMapWidget(QWidget *parent = 0);
-    ~DrawMapWidget();
-
-    void setScene(DrawMapScene * scene);
-
-protected:
-    void changeEvent(QEvent *e);
-    virtual void resizeEvent(QResizeEvent * event);
-
-private:
-    Ui::DrawMapWidget *ui;
-};
-
-#endif // DRAWMAPWIDGET_H
diff --git a/tools/drawMapTest/main.cpp b/tools/drawMapTest/main.cpp
deleted file mode 100644
index 6e7efd9..0000000
--- a/tools/drawMapTest/main.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-#include <QtGui/QApplication>
-#include "mainwindow.h"
-
-int main(int argc, char *argv[])
-{
-    QApplication a(argc, argv);
-    MainWindow w;
-    w.show();
-    return a.exec();
-}
diff --git a/tools/drawMapTest/mainwindow.cpp b/tools/drawMapTest/mainwindow.cpp
deleted file mode 100644
index 41eb6ec..0000000
--- a/tools/drawMapTest/mainwindow.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-#include <QFileDialog>
-
-#include "mainwindow.h"
-#include "ui_mainwindow.h"
-#include "drawmapscene.h"
-
-MainWindow::MainWindow(QWidget *parent) :
-    QMainWindow(parent),
-    ui(new Ui::MainWindow)
-{
-    ui->setupUi(this);
-
-    scene = new DrawMapScene(this);
-    //ui->graphicsView->setScene(scene);
-    ui->drawMapWidget->setScene(scene);
-
-    connect(ui->pbUndo, SIGNAL(clicked()), scene, SLOT(undo()));
-    connect(scene, SIGNAL(pathChanged()), this, SLOT(scene_pathChanged()));
-}
-
-MainWindow::~MainWindow()
-{
-    delete ui;
-}
-
-void MainWindow::changeEvent(QEvent *e)
-{
-    QMainWindow::changeEvent(e);
-    switch (e->type()) {
-    case QEvent::LanguageChange:
-        ui->retranslateUi(this);
-        break;
-    default:
-        break;
-    }
-}
-
-void MainWindow::scene_pathChanged()
-{
-    QString str = scene->encode().toBase64();
-    ui->plainTextEdit->setPlainText(str);
-    ui->sbBytes->setValue(str.size());
-}
-
-void MainWindow::on_pbSave_clicked()
-{
-    QString fileName = QFileDialog::getSaveFileName(this, tr("Save map"), ".");
-
-    if(!fileName.isEmpty())
-    {
-        QFile f(fileName);
-
-        f.open(QIODevice::WriteOnly);
-        f.write(scene->encode());
-    }
-}
-
-void MainWindow::on_pbLoad_clicked()
-{
-    QString fileName = QFileDialog::getOpenFileName(this, tr("Open map file"), ".");
-
-    if(!fileName.isEmpty())
-    {
-        QFile f(fileName);
-
-        f.open(QIODevice::ReadOnly);
-        QByteArray data = f.readAll();
-        scene->decode(data);
-    }
-}
diff --git a/tools/drawMapTest/mainwindow.h b/tools/drawMapTest/mainwindow.h
deleted file mode 100644
index 62a6e5b..0000000
--- a/tools/drawMapTest/mainwindow.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef MAINWINDOW_H
-#define MAINWINDOW_H
-
-#include <QMainWindow>
-
-namespace Ui {
-    class MainWindow;
-}
-
-class DrawMapScene;
-
-class MainWindow : public QMainWindow {
-    Q_OBJECT
-public:
-    MainWindow(QWidget *parent = 0);
-    ~MainWindow();
-
-protected:
-    void changeEvent(QEvent *e);
-
-private:
-    Ui::MainWindow *ui;
-    DrawMapScene * scene;
-
-private slots:
-    void on_pbLoad_clicked();
-    void on_pbSave_clicked();
-    void scene_pathChanged();
-};
-
-#endif // MAINWINDOW_H
diff --git a/tools/drawMapTest/mainwindow.ui b/tools/drawMapTest/mainwindow.ui
deleted file mode 100644
index aa88003..0000000
--- a/tools/drawMapTest/mainwindow.ui
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>MainWindow</class>
- <widget class="QMainWindow" name="MainWindow">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>600</width>
-    <height>400</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>MainWindow</string>
-  </property>
-  <widget class="QWidget" name="centralWidget">
-   <layout class="QGridLayout" name="gridLayout" rowstretch="3,1">
-    <item row="1" column="2">
-     <widget class="QPlainTextEdit" name="plainTextEdit"/>
-    </item>
-    <item row="0" column="0" rowspan="2">
-     <layout class="QVBoxLayout" name="verticalLayout">
-      <item>
-       <widget class="QPushButton" name="pbUndo">
-        <property name="text">
-         <string>Undo</string>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <spacer name="verticalSpacer">
-        <property name="orientation">
-         <enum>Qt::Vertical</enum>
-        </property>
-        <property name="sizeHint" stdset="0">
-         <size>
-          <width>20</width>
-          <height>40</height>
-         </size>
-        </property>
-       </spacer>
-      </item>
-      <item>
-       <widget class="QPushButton" name="pbSave">
-        <property name="text">
-         <string>Save</string>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <widget class="QPushButton" name="pbLoad">
-        <property name="text">
-         <string>Load</string>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <widget class="QSpinBox" name="sbBytes">
-        <property name="readOnly">
-         <bool>true</bool>
-        </property>
-        <property name="buttonSymbols">
-         <enum>QAbstractSpinBox::NoButtons</enum>
-        </property>
-        <property name="suffix">
-         <string> bytes</string>
-        </property>
-        <property name="maximum">
-         <number>999999</number>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </item>
-    <item row="0" column="2">
-     <widget class="DrawMapWidget" name="drawMapWidget" native="true"/>
-    </item>
-   </layout>
-  </widget>
- </widget>
- <layoutdefault spacing="6" margin="11"/>
- <customwidgets>
-  <customwidget>
-   <class>DrawMapWidget</class>
-   <extends>QWidget</extends>
-   <header>drawmapwidget.h</header>
-   <container>1</container>
-  </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
diff --git a/tools/drawMapTest/qaspectratiolayout.cpp b/tools/drawMapTest/qaspectratiolayout.cpp
deleted file mode 100644
index 8af1110..0000000
--- a/tools/drawMapTest/qaspectratiolayout.cpp
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (c) 2009 Nokia Corporation.
- */
-
-#include "qaspectratiolayout.h"
-
-QAspectRatioLayout::QAspectRatioLayout(QWidget* parent, int spacing) : QLayout(parent) {
-        init(spacing);
-}
-
-QAspectRatioLayout::QAspectRatioLayout(int spacing) {
-        init(spacing);
-}
-
-QAspectRatioLayout::~QAspectRatioLayout() {
-        delete item;
-        delete lastReceivedRect;
-        delete _geometry;
-}
-
-void QAspectRatioLayout::init(int spacing) {
-        item = 0;
-        lastReceivedRect = new QRect(0, 0, 0, 0);
-        _geometry = new QRect(0, 0, 0, 0);
-        setSpacing(spacing);
-}
-
-
-/* Adds item if place isn't already taken. */
-void QAspectRatioLayout::add(QLayoutItem* item) {
-        if(!hasItem()) {
-                replaceItem(item);
-        }
-}
-
-/* Adds item if place isn't already taken. */
-void QAspectRatioLayout::addItem(QLayoutItem* item) {
-        if(!hasItem()) {
-                replaceItem(item);
-        }
-}
-
-/* Adds widget if place isn't already taken. */
-void QAspectRatioLayout::addWidget(QWidget* widget) {
-        if(!hasItem()) {
-                replaceItem(new QWidgetItem(widget));
-        }
-}
-
-/* Returns the item pointer and dereferences it here. */
-QLayoutItem* QAspectRatioLayout::take() {
-        QLayoutItem* item = 0;
-        if(this->hasItem()) {
-                item = this->item;
-                this->item = 0;
-        }
-        return item;
-}
-
-/* Returns the item pointer and dereferences it here. */
-QLayoutItem* QAspectRatioLayout::takeAt(int index) {
-        if(index != 0) {
-                return 0;
-        }
-        return this->take();
-}
-
-/* Returns the item pointer. */
-QLayoutItem* QAspectRatioLayout::itemAt(int index) const {
-        if(index != 0) {
-                return 0;
-        }
-        if(hasItem()) {
-                return this->item;
-        }
-        return 0;
-}
-
-/* Checks if we have an item. */
-bool QAspectRatioLayout::hasItem() const {
-        return this->item != 0;
-}
-
-/* Returns the count of items which can be either 0 or 1. */
-int QAspectRatioLayout::count() const {
-        int returnValue = 0;
-        if(hasItem()) {
-                returnValue = 1;
-        }
-        return returnValue;
-}
-
-/* Replaces the item with the new and returns the old. */
-QLayoutItem* QAspectRatioLayout::replaceItem(QLayoutItem* item) {
-        QLayoutItem* old = 0;
-        if(this->hasItem()) {
-                old = this->item;
-        }
-        this->item = item;
-        setGeometry(*this->_geometry);
-        return old;
-}
-
-/* Tells which way layout expands. */
-Qt::Orientations QAspectRatioLayout::expandingDirections() const {
-        return Qt::Horizontal | Qt::Vertical;
-}
-
-/* Tells which size is preferred. */
-QSize QAspectRatioLayout::sizeHint() const {
-        return this->item->minimumSize();
-}
-
-/* Tells minimum size. */
-QSize QAspectRatioLayout::minimumSize() const {
-        return this->item->minimumSize();
-}
-
-/*
- * Tells if heightForWidth calculations is handled.
- * It isn't since width isn't enough to calculate
- * proper size.
- */
-bool QAspectRatioLayout::hasHeightForWidth() const {
-        return false;
-}
-
-/* Replaces lastReceivedRect. */
-void QAspectRatioLayout::setLastReceivedRect(const QRect& rect) {
-        QRect* oldRect = this->lastReceivedRect;
-        this->lastReceivedRect = new QRect(rect.topLeft(), rect.size());
-        delete oldRect;
-}
-
-/* Returns geometry */
-QRect QAspectRatioLayout::geometry() {
-        return QRect(*this->_geometry);
-}
-
-/* Sets geometry to given size. */
-void QAspectRatioLayout::setGeometry(const QRect& rect) {
-        /*
-         * We check if the item is set and
-         * if size is the same previously received.
-         * If either is false nothing is done.
-         */
-        if(!this->hasItem() ||
-           areRectsEqual(*this->lastReceivedRect, rect)) {
-                return;
-        }
-        /* Replace the last received rectangle. */
-        setLastReceivedRect(rect);
-        /* Calculate proper size for the item relative to the received size. */
-        QSize properSize = calculateProperSize(rect.size());
-        /* Calculate center location in the rect and with item size. */
-        QPoint properLocation = calculateCenterLocation(rect.size(), properSize);
-        /* Set items geometry */
-        this->item->setGeometry(QRect(properLocation, properSize));
-        QRect* oldRect = this->_geometry;
-        /* Cache the calculated geometry. */
-        this->_geometry = new QRect(properLocation, properSize);
-        delete oldRect;
-        /* Super classes setGeometry */
-        QLayout::setGeometry(*this->_geometry);
-}
-
-/* Takes the shortest side and creates QSize
- * with the shortest side as width and height. */
-QSize QAspectRatioLayout::calculateProperSize(QSize from) const {
-        QSize properSize;
-        if(from.height() * 2 < from.width()) {
-                properSize.setHeight(from.height() - this->margin());
-                properSize.setWidth(from.height() * 2 - this->margin());
-        }
-        else {
-                properSize.setWidth(from.width() - this->margin());
-                properSize.setHeight(from.width() / 2 - this->margin());
-        }
-        return properSize;
-}
-
-/* Calculates center location from the given height and width for item size. */
-QPoint QAspectRatioLayout::calculateCenterLocation(QSize from,
-                                                   QSize itemSize) const {
-        QPoint centerLocation;
-        if((from.width() - itemSize.width()) > 0) {
-                centerLocation.setX((from.width() - itemSize.width())/2);
-        }
-        if((from.height() - itemSize.height()) > 0) {
-                centerLocation.setY((from.height() - itemSize.height())/2);
-        }
-        return centerLocation;
-}
-
-/* Compares if two QRects are equal. */
-bool QAspectRatioLayout::areRectsEqual(const QRect& a,
-                                       const QRect& b) const {
-        bool result = false;
-        if(a.x() == b.x() &&
-           a.y() == b.y() &&
-           a.height() == b.height() &&
-           a.width() == b.width()) {
-                result = true;
-        }
-        return result;
-}
diff --git a/tools/drawMapTest/qaspectratiolayout.h b/tools/drawMapTest/qaspectratiolayout.h
deleted file mode 100644
index c73525e..0000000
--- a/tools/drawMapTest/qaspectratiolayout.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2009 Nokia Corporation.
- */
-
-#ifndef QASPECTRATIOLAYOUT_H_
-#define QASPECTRATIOLAYOUT_H_
-
-#include <QLayout>
-#include <QPointer>
-#include <QRect>
-#include <QWidgetItem>
-#include <QLayoutItem>
-
-
-class QAspectRatioLayout : public QLayout
-{
-        Q_OBJECT
-
-public:
-        QAspectRatioLayout(QWidget* parent, int spacing =-1);
-        QAspectRatioLayout(int spacing = -1);
-        ~QAspectRatioLayout();
-
-        /* Convenience method */
-        virtual void add(QLayoutItem* item);
-
-/* http://doc.trolltech.com/qlayout.html#addItem */
-        virtual void addItem(QLayoutItem* item);
-        /* http://doc.trolltech.com/qlayout.html#addWidget */
-        virtual void addWidget(QWidget* widget);
-        /* http://doc.trolltech.com/qlayout.html#takeAt */
-        virtual QLayoutItem* takeAt(int index);
-        /* http://doc.trolltech.com/qlayout.html#itemAt */
-        virtual QLayoutItem* itemAt(int index) const;
-        /* http://doc.trolltech.com/qlayout.html#count */
-        virtual int count() const;
-
-        /*
-         * These are ours since we do have only one item.
-         */
-        virtual QLayoutItem* replaceItem(QLayoutItem* item);
-        virtual QLayoutItem* take();
-        virtual bool hasItem() const;
-
-/* http://doc.trolltech.com/qlayout.html#expandingDirections */
-        virtual Qt::Orientations expandingDirections() const;
-
-        /*
-         * This method contains most of the juice of this article.
-         * http://doc.trolltech.com/qlayoutitem.html#setGeometry
-         */
-        virtual void setGeometry(const QRect& rect);
-        /* http://doc.trolltech.com/qlayoutitem.html#geometry */
-        virtual QRect geometry();
-
-        /* http://doc.trolltech.com/qlayoutitem.html#sizeHint */
-        virtual QSize sizeHint() const;
-        /* http://doc.trolltech.com/qlayout.html#minimumSize */
-        virtual QSize minimumSize() const;
-        /* http://doc.trolltech.com/qlayoutitem.html#hasHeightForWidth */
-        virtual bool hasHeightForWidth() const;
-
-private:
-        /* Saves the last received rect. */
-        void setLastReceivedRect(const QRect& rect);
-        /* Used to initialize the object. */
-        void init(int spacing);
-        /* Calculates the maximum size for the item from the assigned size. */
-        QSize calculateProperSize(QSize from) const;
-        /* Calculates the center location from the assigned size and
-         * the items size. */
-        QPoint calculateCenterLocation(QSize from, QSize itemSize) const;
-        /* Check if two QRects are equal */
-        bool areRectsEqual(const QRect& a, const QRect& b) const;
-        /* Contains item reference */
-        QLayoutItem* item;
-        /*
-         * Used for caching so we won't do calculations every time
-         * setGeometry is called.
-         */
-        QRect* lastReceivedRect;
-        /* Contains geometry */
-        QRect* _geometry;
-
-};
-
-#endif /* QASPECTRATIOLAYOUT_H_ */

-- 
Worms style game



More information about the Pkg-games-commits mailing list