Merge default (add a bunch of FIXMEs) qmlfrontend
authorunc0rr
Mon, 16 Nov 2015 22:57:24 +0300
branchqmlfrontend
changeset 11403 b894922d58cc
parent 11076 fcbdee9cdd74 (current diff)
parent 11402 bea08a303cb7 (diff)
child 11413 ffff8a0d1a76
Merge default (add a bunch of FIXMEs)
.hgignore
CMakeLists.txt
README
cmake_modules/FindSDL1or2.cmake
gameServer/OfficialServer/checker.hs
hedgewars/ArgParsers.pas
hedgewars/CMakeLists.txt
hedgewars/SDLh.pas
hedgewars/hwLibrary.pas
hedgewars/hwengine.pas
hedgewars/sdlmain/CMakeLists.txt
hedgewars/sdlmain/SDLMain.h
hedgewars/sdlmain/SDLMain.m
hedgewars/uDebug.pas
hedgewars/uFLIPC.pas
hedgewars/uFLNet.pas
hedgewars/uIO.pas
hedgewars/uInputHandler.pas
hedgewars/uLocale.pas
hedgewars/uMisc.pas
hedgewars/uPhysFSLayer.pas
hedgewars/uRender.pas
hedgewars/uTypes.pas
hedgewars/uVariables.pas
misc/winutils/include/GL/glut.h
project_files/HedgewarsMobile/Classes/Appirater.h
project_files/HedgewarsMobile/Classes/Appirater.m
project_files/HedgewarsMobile/Classes/SettingsContainerViewController.h
project_files/HedgewarsMobile/Classes/SettingsContainerViewController.m
project_files/HedgewarsMobile/Locale/Turkish.lproj/About.strings
project_files/HedgewarsMobile/Locale/Turkish.lproj/Localizable.strings
project_files/HedgewarsMobile/Locale/Turkish.lproj/Scheme.strings
--- a/.hgignore	Tue Sep 08 19:20:58 2015 +0300
+++ b/.hgignore	Mon Nov 16 22:57:24 2015 +0300
@@ -26,7 +26,7 @@
 glob:*.diff
 glob:vittorio.*
 glob:project_files/HedgewarsMobile/Data/
-glob:project_files/HedgewarsMobile/build/
+glob:project_files/HedgewarsMobile/Build/
 glob:gameServer/dist/
 glob:misc/liblua/Xcode/build/
 glob:misc/libphysfs/Xcode/build/
@@ -72,4 +72,14 @@
 glob:share/Info.plist
 glob:CTestTestfile.cmake
 glob:arch.c
+glob:*.swp
+glob:*~.nib
+glob:*.pbxuser
+glob:*.perspective
+glob:*.perspectivev3
+glob:*.project.xcworkspace
+glob:*.xcuserdata
+glob:xcuserdata
+glob:*.mode1v3
+glob:*.mode2v3
 
--- a/.hgtags	Tue Sep 08 19:20:58 2015 +0300
+++ b/.hgtags	Mon Nov 16 22:57:24 2015 +0300
@@ -63,3 +63,14 @@
 af0520a6bf0061b27f8321514d35fcd2b1ef5f9c 0.9.20-release
 7e55468ffe384a3065524c483eb5e3cdb1658fd5 0.9.21-release
 7e55468ffe384a3065524c483eb5e3cdb1658fd5 fab746a3597e
+0f5961910e2712582b162abd08ae3eed330cc978 Nice one
+d9622394ec9c2974a84b9b4d9e6c0ac26c4060ff 0.9.22-RC
+0f5961910e2712582b162abd08ae3eed330cc978 Nice one
+0000000000000000000000000000000000000000 Nice one
+4c4f22cc3fa4e6c1e5cd6cce35350dd93478415f 0.9.22-release
+4c4f22cc3fa4e6c1e5cd6cce35350dd93478415f 0.9.22-release
+9621fdcad96589b3fd78713a0f31e72f26f068bb 0.9.22-release
+7e55468ffe384a3065524c483eb5e3cdb1658fd5 fab746a3597e
+0000000000000000000000000000000000000000 fab746a3597e
+d9622394ec9c2974a84b9b4d9e6c0ac26c4060ff 0.9.22-RC
+0000000000000000000000000000000000000000 0.9.22-RC
--- a/.travis.yml	Tue Sep 08 19:20:58 2015 +0300
+++ b/.travis.yml	Mon Nov 16 22:57:24 2015 +0300
@@ -6,24 +6,18 @@
   - gcc
   - clang
 env:
-  # Default build. Release.
   - BUILD_ARGS="-DCMAKE_BUILD_TYPE=Release"
-  # Debug build
   - BUILD_ARGS="-DCMAKE_BUILD_TYPE=Debug"
-  # Everything that's optional
-  - BUILD_ARGS="-DBUILD_ENGINE_C=1"
-  - BUILD_ARGS="-DNOPNG=1"
-  - BUILD_ARGS="-DNOVIDEOREC=1"
-  - BUILD_ARGS="-DNOSERVER=1"
-  - BUILD_ARGS="-DLUA_SYSTEM=0"
-  - BUILD_ARGS="-DPHYSFS_SYSTEM=0"
-  - BUILD_ARGS="-DGL2=1"
+  - BUILD_ARGS="-DNOSERVER=1 -DBUILD_ENGINE_C=1"
+  - BUILD_ARGS="-DNOSERVER=1 -DNOVIDEOREC=1 -DNOPNG=1"
+  - BUILD_ARGS="-DNOSERVER=1 -DLUA_SYSTEM=0 -DPHYSFS_SYSTEM=0"
 matrix:
   allow_failures:
     # Failures we expect here
 before_install:
+  - sudo add-apt-repository -y ppa:zoogie/sdl2-snapshots
   - sudo apt-get update -qq
-  - sudo apt-get install debhelper cmake dpkg-dev libqt4-dev qt4-qmake libphysfs-dev libsdl1.2-dev libsdl-ttf2.0-dev libsdl-mixer1.2-dev libsdl-image1.2-dev libsdl-net1.2-dev bzip2 ghc libghc-mtl-dev libghc-parsec3-dev libghc-bytestring-show-dev libghc-vector-dev libghc-zlib-dev libghc-random-dev libghc-stm-dev libghc-network-dev libghc-dataenc-dev libghc-hslogger-dev libghc-utf8-string-dev libghc-sha-dev libghc-entropy-dev liblua5.1-0-dev imagemagick fpc fp-compiler fp-units-misc libpng-dev fp-units-gfx libavcodec-dev libavformat-dev freeglut3-dev libglew1.6-dev
+  - sudo apt-get install debhelper cmake dpkg-dev libqt4-dev qt4-qmake libphysfs-dev libsdl2-dev libsdl2-ttf-dev libsdl2-mixer-dev libsdl2-image-dev libsdl2-net-dev bzip2 ghc libghc-mtl-dev libghc-parsec3-dev libghc-bytestring-show-dev libghc-vector-dev libghc-zlib-dev libghc-random-dev libghc-stm-dev libghc-network-dev libghc-dataenc-dev libghc-hslogger-dev libghc-utf8-string-dev libghc-sha-dev libghc-entropy-dev liblua5.1-0-dev imagemagick fpc fp-compiler fp-units-misc libpng-dev fp-units-gfx libavcodec-dev libavformat-dev libglew1.6-dev
 script: 
   - mkdir build && cd build && cmake $BUILD_ARGS .. && make VERBOSE=1 && make test_verbose
 notifications:
--- a/CMakeLists.txt	Tue Sep 08 19:20:58 2015 +0300
+++ b/CMakeLists.txt	Mon Nov 16 22:57:24 2015 +0300
@@ -8,6 +8,12 @@
     endif()
 endforeach()
 
+foreach(hwpolicy CMP0026)
+    if(POLICY ${hwpolicy})
+        cmake_policy(SET ${hwpolicy} OLD)
+    endif()
+endforeach()
+
 set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules")
 include(${CMAKE_MODULE_PATH}/utils.cmake)
 
@@ -52,13 +58,15 @@
 #versioning
 set(CPACK_PACKAGE_VERSION_MAJOR 0)
 set(CPACK_PACKAGE_VERSION_MINOR 9)
-set(CPACK_PACKAGE_VERSION_PATCH 22)
-set(HEDGEWARS_PROTO_VER 50)
+set(CPACK_PACKAGE_VERSION_PATCH 23)
+set(HEDGEWARS_PROTO_VER 52)
 set(HEDGEWARS_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
 include(${CMAKE_MODULE_PATH}/revinfo.cmake)
 
 message(STATUS "Building ${HEDGEWARS_VERSION}-r${HEDGEWARS_REVISION} (${HEDGEWARS_HASH})")
 
+#io library paths
+include(${CMAKE_MODULE_PATH}/paths.cmake)
 #general utilities
 include(${CMAKE_MODULE_PATH}/utils.cmake)
 #paths initialization
@@ -110,18 +118,18 @@
     endif()
 endif()
 
-list(APPEND haskell_flags ${ghflags_parsed} "-O2")
 
 #get BUILD_TYPE and enable/disable optimisation
 message(STATUS "Using ${CMAKE_BUILD_TYPE} configuration")
 if(CMAKE_BUILD_TYPE MATCHES "DEBUG")
     list(APPEND haskell_flags "-Wall"       # all warnings
                               "-debug"      # debug mode
-                              "-dcore-lint" # internal sanity check
                               "-fno-warn-unused-do-bind"
+                              "-O0"
                               )
 else()
     list(APPEND haskell_flags "-w" # no warnings
+                              "-O2"
                               )
 endif()
 
--- a/ChangeLog.txt	Tue Sep 08 19:20:58 2015 +0300
+++ b/ChangeLog.txt	Mon Nov 16 22:57:24 2015 +0300
@@ -1,22 +1,40 @@
 + features
 * bugfixes
 
+0.9.22 -> 0.9.23
+ * Hammer damage is now rounded down. This means it will cause NO DAMAGE to a hedgehog with less than 3 hp.
+ * Fixed bee not being affected by wrap world edge while still being thrown
+ * Fixed turn not ending when sticky mine was trapped on rubberband
+ * Various other fixes
+
 0.9.21 -> 0.9.22
+ + New Weapon / Map object: AirMine (floating mine that will follow nearby hedgehogs)
  + Extensive changes to TechRacer: Variable terrain types, enhanced parameters, hwmap interpreter, fuel limiter, etc. 
+ + HedgeEditor - create missions/etc. in-game! see http://hedgewars.org/HedgeEditor
  + Map previews can now take script parameters into account and preview waypoints in TechRacer
  + Added a couple new flags
- + Small improvements to the interface and in-game chat
- + Divided teams options will now just be ignored when more/less than 2 teams, instead of displaying a fatal error
+ + Various tweaks to the interface and in-game chat
+ + Divided teams options will now just be ignored when more/less than 2 teams/clans, instead of displaying a fatal error
  + Added 6 TechRacer maps to TechMaps
  + Added 3 SpeedShoppa Challenges: Shoppa Love, Ropes and Crates, The Customer is King
  + Hammer damage is now rounded up. This means it can be used to execute hedgehogs with only 1 hp.
  + Improved "Art" theme.
  * Generated bridges/girders are now connected better to the land mass
  * Fixed rubberband sprite
+ * Fixed Wind-Indicator being wrong in certain situations
+ * Melon Bomb Pieces now bounce on Rubberband
+ * Reduced menu music volume
  * The game will now fallback to default voicepack if a team's voicepack is not locally installed. (Instead of rendering team voiceless)
  * Hammer now does more damage when the Extra-Damage utility is used
  * Many other bug fixes
 
+Lua-API:
+ + New map parameter: MapFeatureSize -- numeric representation of detail slider below map preview; use within onGameInit()/onPreviewInit()
+ + New function: SetMaxBuildDistance([ distInPx ]) -- specify how many pixels away a hedgehog can still place girders/etc. set to 0 for no limit; call with no param to reset to default
+ + New hook: onSuddenDeath() -- called by engine when sudden death begins
+ * Previously missing gear states are now available (gstSubmersible, gstFrozen and gstNoGravity)
+ * Fixed OnHogAttack giving the incorrect AmmoType (amNothing) under certain conditions
+
 0.9.20 -> 0.9.21:
  + New type of randomly generated maps: Perlin Maps.
  + Old Random generated maps are more diverse now.
--- a/INSTALL	Tue Sep 08 19:20:58 2015 +0300
+++ b/INSTALL	Mon Nov 16 22:57:24 2015 +0300
@@ -2,10 +2,10 @@
  - CMake >= 2.6.0
  - FreePascal >= 2.2.4
  - Qt >= 4.7.0
- - SDL >= 1.2.5
- - SDL_net >= 1.2.5
- - SDL_mixer >= 1.2
- - SDL_image >= 1.2
+ - SDL >= 2.0
+ - SDL_net >= 2.0
+ - SDL_mixer >= 2.0
+ - SDL_image >= 2.0
  - SDL_ttf >= 2.0
  - Lua = 5.1.0
  - Physfs >= 2.0.0
@@ -16,7 +16,6 @@
  - hslogger package
 For videorecording:
  - FFmpeg or LibAV
- - GLUT (when SDL < 2)
 For compressed screenshots:
  - libpng
 
--- a/QTfrontend/CMakeLists.txt	Tue Sep 08 19:20:58 2015 +0300
+++ b/QTfrontend/CMakeLists.txt	Mon Nov 16 22:57:24 2015 +0300
@@ -20,8 +20,10 @@
    message(FATAL_ERROR "This version of Qt is known *not* to work, please update or use a lower version")
 endif()
 
-find_package(SDL1or2)            #video in SDLInteraction
-find_package(SDL_mixer REQUIRED) #audio in SDLInteraction
+find_package(SDL2 REQUIRED)
+find_package(SDL2_mixer REQUIRED) #audio in SDLInteraction
+include_directories(${SDL2_INCLUDE_DIR})
+include_directories(${SDL2MIXER_INCLUDE_DIR})
 
 if(LIBAV_FOUND)
     add_definitions(-DVIDEOREC -D__STDC_CONSTANT_MACROS)
@@ -60,8 +62,6 @@
 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ui/widget)
 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/util)
 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/util/platform)
-include_directories(${SDL_INCLUDE_DIR})
-include_directories(${SDLMIXER_INCLUDE_DIR})
 include_directories(BEFORE ${PHYSFS_INCLUDE_DIR})
 include_directories(BEFORE ${PHYSLAYER_INCLUDE_DIR})
 include_directories(${LUA_INCLUDE_DIR}) #brought by physlayer hwpacksmounter.h
@@ -204,13 +204,16 @@
 list(APPEND HW_LINK_LIBS
     physfs physlayer
     ${QT_LIBRARIES}
-    ${SDL_LIBRARY}
-    ${SDLMIXER_LIBRARY}
+    )
+
+list(APPEND HW_LINK_LIBS
+    ${SDL2_LIBRARY}
+    ${SDL2MIXER_LIBRARY}
     )
     
 if(WIN32 AND NOT UNIX)
-    if(NOT SDL_LIBRARY)
-        list(APPEND HW_LINK_LIBS SDL)
+    if(NOT SDL2_LIBRARY)
+        list(APPEND HW_LINK_LIBS SDL2)
     endif()
 
     list(APPEND HW_LINK_LIBS
--- a/QTfrontend/game.cpp	Tue Sep 08 19:20:58 2015 +0300
+++ b/QTfrontend/game.cpp	Mon Nov 16 22:57:24 2015 +0300
@@ -17,7 +17,6 @@
  */
 
 #include <QApplication>
-#include <QClipboard>
 
 #include <QString>
 #include <QCheckBox>
@@ -261,18 +260,6 @@
                 .arg(QString::fromUtf8(msg.mid(2).left(size - 4))));
             return;
         }
-        case 'y':
-        {
-            // copy string to clipboard
-            QApplication::clipboard()->setText(QString::fromUtf8(msg.mid(2)));
-            break;
-        }
-        case 'Y':
-        {
-            // paste clipboard to game
-            SendIPC(QString("Y").toAscii() + QApplication::clipboard()->text().toUtf8().left(250).replace('\n', ' '));
-            break;
-        }
         case 'i':
         {
             emit GameStats(msg.at(2), QString::fromUtf8(msg.mid(3)));
--- a/QTfrontend/gameuiconfig.cpp	Tue Sep 08 19:20:58 2015 +0300
+++ b/QTfrontend/gameuiconfig.cpp	Mon Nov 16 22:57:24 2015 +0300
@@ -86,10 +86,11 @@
     else Form->ui.pageOptions->CBResolution->setCurrentIndex(t);
 
     // Default the windowed resolution to 5/6 of the screen size
-    int screenWidth = SDL_GetVideoInfo()->current_w * 5 / 6;
-    int screenHeight = SDL_GetVideoInfo()->current_h * 5 / 6;
-    QString widthStr; widthStr.setNum(screenWidth);
-    QString heightStr; heightStr.setNum(screenHeight);
+    QSize screenSize = SDLInteraction::instance().getCurrentResolution();
+    screenSize *= 5.0 / 6;
+
+    QString widthStr = QString::number(screenSize.width());
+    QString heightStr = QString::number(screenSize.height());
     QString wWidth = value("video/windowedWidth", widthStr).toString();
     QString wHeight = value("video/windowedHeight", heightStr).toString();
     // If left blank reset the resolution to the default
--- a/QTfrontend/main.cpp	Tue Sep 08 19:20:58 2015 +0300
+++ b/QTfrontend/main.cpp	Mon Nov 16 22:57:24 2015 +0300
@@ -37,6 +37,8 @@
 #include "FileEngine.h"
 #include "MessageDialog.h"
 
+#include "SDLInteraction.h"
+
 #ifdef _WIN32
 #include <Shlobj.h>
 #elif defined __APPLE__
@@ -154,6 +156,8 @@
     cocoaInit = new CocoaInitializer(); // Creates the autoreleasepool preventing cocoa object leaks on OS X.
 #endif
 
+    SDLInteraction::instance();
+
     HWApplication app(argc, argv);
     app.setAttribute(Qt::AA_DontShowIconsInMenus,false);
 
--- a/QTfrontend/res/html/about.html	Tue Sep 08 19:20:58 2015 +0300
+++ b/QTfrontend/res/html/about.html	Mon Nov 16 22:57:24 2015 +0300
@@ -35,6 +35,7 @@
         Keybinds, feedback, maps and hats interfaces: Drew Gottlieb &lt;<a href="mailto:gottlieb.drew@gmail.com">gottlieb.drew@gmail.com</a>&gt;<br>
         Login dialogs, frontend improvements: Ondrej Skopek &lt;<a href="mailto:skopekondrej@gmail.com">skopekondrej@gmail.com</a>&gt;<br>
         Icegun weapon: Julia Struchenko &lt;<a href="mailto:urbertar@gmail.com">urbertar@gmail.com</a>&gt;<br>
+        iPhone/iPad ports: Anton Malmygin &lt;<a href="mailto:antonc27@mail.ru">antonc27@mail.ru</a>&gt;<br>
         </p>
 
         <h2>Art:</h2>
@@ -82,7 +83,7 @@
             Lithuanian: Lukas Urbonas &lt;<a href="mailto:lukasu08@gmail.com">lukasu08@gmail.com</a>&gt;<br>
             Polish: Maciej Mroziński &lt;<a href="mailto:mynick2@o2.pl">mynick2@o2.pl</a>&gt;, Wojciech Latkowski &lt;<a href="mailto:magik17l@gmail.com">magik17l@gmail.com</a>&gt;, Piotr Mitana, Maciej Górny<br>
             Portuguese: Fábio Canário &lt;<a href="mailto:inufabie@gmail.com">inufabie@gmail.com</a>&gt;<br>
-            Russian: Andrey Korotaev &lt;<a href="mailto:unC0Rr@gmail.com">unC0Rr@gmail.com</a>&gt;, Vitaly Novichkov &lt;<a href="mailto:admin@wohlnet.ru">admin@wohlnet.ru</a>&gt;<br>
+            Russian: Andrey Korotaev &lt;<a href="mailto:unC0Rr@gmail.com">unC0Rr@gmail.com</a>&gt;, Vitaly Novichkov &lt;<a href="mailto:admin@wohlnet.ru">admin@wohlnet.ru</a>&gt;, Anton Malmygin &lt;<a href="mailto:antonc27@mail.ru">antonc27@mail.ru</a>&gt;<br>
             Slovak: Jose Riha<br>
             Spanish: Carlos Vives &lt;<a href="mailto:mail@carlosvives.es">mail@carlosvives.es</a>&gt;<br>
             Swedish: Niklas Grahn &lt;<a href="mailto:raewolusjoon@yaoo.com">raewolusjoon@yaoo.com</a>&gt;, Henrik Rostedt &lt;<a href="mailto:henrik.rostedt@gmail.com">henrik.rostedt@gmail.com</a>&gt;<br>
--- a/QTfrontend/ui/widget/about.cpp	Tue Sep 08 19:20:58 2015 +0300
+++ b/QTfrontend/ui/widget/about.cpp	Mon Nov 16 22:57:24 2015 +0300
@@ -101,14 +101,17 @@
     libinfo.append(QString(tr("Unknown Compiler")).arg(__VERSION__) + QString("<br>"));
 #endif
 
-    const SDL_version *sdl_ver = SDL_Linked_Version();
-    libinfo.append(QString("<a href=\"http://www.libsdl.org/\">SDL</a> version: %1.%2.%3<br>")
+    const SDL_version *sdl_ver;
+    SDL_version sdl_version;
+    SDL_GetVersion(&sdl_version);
+    sdl_ver = &sdl_version;
+    libinfo.append(QString("<a href=\"http://www.libsdl.org/\">SDL2</a> version: %1.%2.%3<br>")
         .arg(sdl_ver->major)
         .arg(sdl_ver->minor)
         .arg(sdl_ver->patch));
 
     const SDL_version *sdlmixer_ver = Mix_Linked_Version();
-    libinfo.append(QString("<a href=\"http://www.libsdl.org/\">SDL_mixer</a> version: %1.%2.%3<br>")
+    libinfo.append(QString("<a href=\"http://www.libsdl.org/\">SDL2_mixer</a> version: %1.%2.%3<br>")
         .arg(sdlmixer_ver->major)
         .arg(sdlmixer_ver->minor)
         .arg(sdlmixer_ver->patch));
--- a/QTfrontend/util/LibavInteraction.cpp	Tue Sep 08 19:20:58 2015 +0300
+++ b/QTfrontend/util/LibavInteraction.cpp	Mon Nov 16 22:57:24 2015 +0300
@@ -21,7 +21,9 @@
 #if VIDEOREC
 extern "C"
 {
+#include "libavcodec/avcodec.h"
 #include "libavformat/avformat.h"
+#include "libavutil/avutil.h"
 }
 
 #include <QVector>
@@ -30,13 +32,28 @@
 
 #include "HWApplication.h"
 
-#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 25, 0)
-#define CodecID AVCodecID
+// compatibility section
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 8, 0)
+#define av_codec_is_encoder(x)          x->encode
+#endif
+
+#if LIBAVCODEC_VERSION_MAJOR < 55
+#define AVCodecID                       CodecID
+#endif
+
+#if LIBAVFORMAT_VERSION_MAJOR < 54
+#define avformat_find_stream_info(x, y) av_find_stream_info(x)
+#define avformat_close_input(x)         av_close_input_file(*(x))
+#endif
+
+#if LIBAVUTIL_VERSION_MAJOR < 54
+#define AVPixelFormat                   PixelFormat
+#define AV_PIX_FMT_YUV420P              PIX_FMT_YUV420P
 #endif
 
 struct Codec
 {
-    CodecID id;
+    AVCodecID id;
     bool isAudio;
     QString shortName; // used for identification
     QString longName; // used for displaying to user
@@ -56,7 +73,7 @@
 QMap<QString,Format> formats;
 
 // test if given format supports given codec
-bool FormatQueryCodec(AVOutputFormat *ofmt, enum CodecID codec_id)
+bool FormatQueryCodec(AVOutputFormat *ofmt, enum AVCodecID codec_id)
 {
 #if LIBAVFORMAT_VERSION_MAJOR >= 54
     return avformat_query_codec(ofmt, codec_id, FF_COMPLIANCE_NORMAL) == 1;
@@ -76,11 +93,7 @@
     AVCodec* pCodec = NULL;
     while ((pCodec = av_codec_next(pCodec)))
     {
-#if LIBAVCODEC_VERSION_MAJOR >= 54
         if (!av_codec_is_encoder(pCodec))
-#else
-        if (!pCodec->encode)
-#endif
             continue;
 
         if (pCodec->type != AVMEDIA_TYPE_VIDEO && pCodec->type != AVMEDIA_TYPE_AUDIO)
@@ -106,8 +119,8 @@
             if (!pCodec->pix_fmts)
                 continue;
             bool yuv420Supported = false;
-            for (const PixelFormat* pfmt = pCodec->pix_fmts; *pfmt != -1; pfmt++)
-                if (*pfmt == PIX_FMT_YUV420P)
+            for (const enum AVPixelFormat* pfmt = pCodec->pix_fmts; *pfmt != -1; pfmt++)
+                if (*pfmt == AV_PIX_FMT_YUV420P)
                 {
                     yuv420Supported = true;
                     break;
@@ -121,7 +134,7 @@
             if (!pCodec->sample_fmts)
                 continue;
             bool s16Supported = false;
-            for (const AVSampleFormat* pfmt = pCodec->sample_fmts; *pfmt != -1; pfmt++)
+            for (const enum AVSampleFormat* pfmt = pCodec->sample_fmts; *pfmt != -1; pfmt++)
                 if (*pfmt == AV_SAMPLE_FMT_S16)
                 {
                     s16Supported = true;
@@ -274,11 +287,7 @@
     QByteArray utf8path = filepath.toUtf8();
     if (avformat_open_input(&pContext, utf8path.data(), NULL, NULL) < 0)
         return "";
-#if LIBAVFORMAT_VERSION_MAJOR < 53
-    if (av_find_stream_info(pContext) < 0)
-#else
     if (avformat_find_stream_info(pContext, NULL) < 0)
-#endif
         return "";
 
     int s = float(pContext->duration)/AV_TIME_BASE;
@@ -312,11 +321,7 @@
     AVDictionaryEntry* pComment = av_dict_get(pContext->metadata, "comment", NULL, 0);
     if (pComment)
         desc += QString("\n") + pComment->value;
-#if LIBAVFORMAT_VERSION_MAJOR < 53
-    av_close_input_file(pContext);
-#else
     avformat_close_input(&pContext);
-#endif
     return desc;
 }
 
--- a/QTfrontend/util/SDLInteraction.cpp	Tue Sep 08 19:20:58 2015 +0300
+++ b/QTfrontend/util/SDLInteraction.cpp	Mon Nov 16 22:57:24 2015 +0300
@@ -85,19 +85,15 @@
 {
     QStringList result;
 
-    SDL_Rect **modes;
+    int modesNumber = SDL_GetNumDisplayModes(0);
+    SDL_DisplayMode mode;
 
-    modes = SDL_ListModes(NULL, SDL_FULLSCREEN);
-
-    if((modes == (SDL_Rect **)0) || (modes == (SDL_Rect **)-1))
+    for(int i = 0; i < modesNumber; ++i)
     {
-        result << "640x480";
-    }
-    else
-    {
-        for(int i = 0; modes[i]; ++i)
-            if ((modes[i]->w >= 640) && (modes[i]->h >= 480))
-                result << QString("%1x%2").arg(modes[i]->w).arg(modes[i]->h);
+        SDL_GetDisplayMode(0, i, &mode);
+
+        if ((mode.w >= 640) && (mode.h >= 480))
+            result << QString("%1x%2").arg(mode.w).arg(mode.h);
     }
 
     return result;
@@ -108,6 +104,9 @@
 {
     QStringList result;
 
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+// TODO or not TODO?
+#else
     int i = 0;
     while(i < 1024 && sdlkeys[i][1][0] != '\0')
         i++;
@@ -181,7 +180,8 @@
 
     // Terminate the list
     sdlkeys[i][0][0] = '\0';
-    sdlkeys[i][1][0] = '\0';
+    sdlkeys[i][1][0] = '\0';   
+#endif
 }
 
 
@@ -243,7 +243,7 @@
     if (!m_audioInitialized) return;
 
     if (m_music == NULL)
-        m_music = Mix_LoadMUS_RW(PHYSFSRWOPS_openRead(m_musicTrack.toLocal8Bit().constData()));
+        m_music = Mix_LoadMUS_RW(PHYSFSRWOPS_openRead(m_musicTrack.toLocal8Bit().constData()), 0);
 
     Mix_VolumeMusic(MIX_MAX_VOLUME/4);
     Mix_FadeInMusic(m_music, -1, 1750);
@@ -264,3 +264,12 @@
     m_isPlayingMusic = false;
 }
 
+
+QSize SDLInteraction::getCurrentResolution()
+{
+    SDL_DisplayMode mode;
+
+    SDL_GetDesktopDisplayMode(0, &mode);
+
+    return QSize(mode.w, mode.h);
+}
--- a/QTfrontend/util/SDLInteraction.h	Tue Sep 08 19:20:58 2015 +0300
+++ b/QTfrontend/util/SDLInteraction.h	Mon Nov 16 22:57:24 2015 +0300
@@ -27,7 +27,15 @@
 
 #include <QMap>
 #include <QStringList>
+#include <QSize>
 
+// workaround some strange Qt and SLD2 interaction
+#ifdef Q_OS_MAC
+#  ifdef MAC_OS_X_VERSION_MIN_REQUIRED
+#    undef MAC_OS_X_VERSION_MIN_REQUIRED
+#    define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_6
+#  endif
+#endif
 #include "SDL_mixer.h"
 
 /**
@@ -103,6 +111,8 @@
 
         /// Fades out and stops the background music (if playing).
         void stopMusic();
+
+        QSize getCurrentResolution();
 };
 
 
--- a/README	Tue Sep 08 19:20:58 2015 +0300
+++ b/README	Mon Nov 16 22:57:24 2015 +0300
@@ -1,46 +1,1 @@
-Hedgewars - a turn based strategy game.
-=======================================
-
-Copyright 2004-2015 Andrey Korotaev <unC0Rr@gmail.com> and others.
-See QTfrontend/res/html/about.html and CREDITS for a complete list of authors.
-
-Licence:
---------
-Source code is distributed under the terms of the GNU General Public Licence
-version 2; images and sounds are distributed under the terms of the GNU Free
-Documentation Licence version 1.2. See the COPYING file for the full text of
-the licenses.
-
-Instructions:
--------------
-See our wiki at: https://code.google.com/p/hedgewars/wiki/BuildingHedgewars
-
-You can find an outline of the necessary dependencies in the INSTALL file.
-
-Source code:
-------------
-Our main repository is located at http://hedgewars.googlecode.com using
-Mercurial as DVCS. A Git repository is also available (mirrored daily)
-at https://github.com/hedgewars/hw
-
-Contribute:
------------
-If you see a bug or have any suggestion please use the official bug tracker at
-http://code.google.com/p/hedgewars/issues/list or the integrated feedback
-button.
-
-If you want to help or get to know the sources better you can do that with some
-easy tasks from http://code.google.com/p/hedgewars/wiki/TODO. We also have an
-extended API in LUA to customize your adventures in our wiki at
-http://code.google.com/p/hedgewars/wiki/LuaAPI.
-
-If you know your way through the code feel free to send a patch or open a pull
-request. The best LUA scripts get released in the official DLC page and later
-integrated in the next version.
-
-Contact:
---------
-* IRC channel     - irc://irc.freenode.net/hedgewars
-* community forum - http://www.hedgewars.org/forum
-* mailing list    - https://mail.gna.org/listinfo/hedgewars-dev
-
+README.md
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.md	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,48 @@
+Hedgewars - a turn based strategy game.
+=======================================
+
+[![Build Status](https://travis-ci.org/hedgewars/hw.svg)](https://travis-ci.org/hedgewars/hw)
+
+Copyright 2004-2015 Andrey Korotaev <unC0Rr@gmail.com> and others.
+See QTfrontend/res/html/about.html and CREDITS for a complete list of authors.
+
+Licence:
+--------
+Source code is distributed under the terms of the GNU General Public Licence
+version 2; images and sounds are distributed under the terms of the GNU Free
+Documentation Licence version 1.2. See the COPYING file for the full text of
+the licenses.
+
+Instructions:
+-------------
+See our wiki at: http://hedgewars.org/kb/BuildingHedgewars
+
+You can find an outline of the necessary dependencies in the INSTALL file.
+
+Source code:
+------------
+Our main repository is located at http://hg.hedgewars.org/hedgewars/ using
+Mercurial as DVCS. A Git repository is also available (mirrored daily)
+at https://github.com/hedgewars/hw
+
+Contribute:
+-----------
+If you see a bug or have any suggestion please use the official bug tracker at
+http://code.google.com/p/hedgewars/issues/list or the integrated feedback
+button.
+
+If you want to help or get to know the sources better you can do that with some
+easy tasks from http://hedgewars.org/kb/TODO. We also have an
+extended API in LUA to customize your adventures in our wiki at
+http://hedgewars.org/kb/LuaAPI.
+
+If you know your way through the code feel free to send a patch or open a pull
+request. The best LUA scripts get released in the official DLC page and later
+integrated in the next version.
+
+Contact:
+--------
+* IRC channel     - irc://irc.freenode.net/hedgewars
+* community forum - http://www.hedgewars.org/forum
+* mailing list    - https://mail.gna.org/listinfo/hedgewars-dev
+
--- a/cmake_modules/CheckHaskellModuleExists.cmake	Tue Sep 08 19:20:58 2015 +0300
+++ b/cmake_modules/CheckHaskellModuleExists.cmake	Mon Nov 16 22:57:24 2015 +0300
@@ -11,7 +11,7 @@
 
 macro(CHECK_HASKELL_MODULE_EXISTS MODULE FUNCTION PARAMCOUNT LIBRARY)
   set(VARIABLE "HS_MODULE_${LIBRARY}_${FUNCTION}")
-  if("${VARIABLE}" MATCHES "^${VARIABLE}$")
+  if(${VARIABLE} MATCHES ^${VARIABLE}$)
     message(STATUS "Looking for ${FUNCTION} in ${MODULE}")
 
     set(PARAMETERS "")
--- a/cmake_modules/FindSDL1or2.cmake	Tue Sep 08 19:20:58 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-find_package(SDL QUIET)
-
-if(NOT SDL_FOUND)
-    find_package(SDL2 REQUIRED)
-    set(SDL_INCLUDE_DIR ${SDL2_INCLUDE_DIR})
-    set(SDL_LIBRARY ${SDL2_LIBRARY})
-endif()
-
-if(NOT SDL_VERSION)
-    #find which version of SDL we have
-    find_file(sdlversion_h SDL_version.h ${SDL_INCLUDE_DIR})
-    if(sdlversion_h)
-        file(STRINGS ${sdlversion_h} sdl_majorversion_tmp REGEX "SDL_MAJOR_VERSION[\t' ']+[0-9]+")
-        file(STRINGS ${sdlversion_h} sdl_minorversion_tmp REGEX "SDL_MINOR_VERSION[\t' ']+[0-9]+")
-        file(STRINGS ${sdlversion_h} sdl_patchversion_tmp REGEX "SDL_PATCHLEVEL[\t' ']+[0-9]+")
-        string(REGEX MATCH "([0-9]+)" sdl_majorversion "${sdl_majorversion_tmp}")
-        string(REGEX MATCH "([0-9]+)" sdl_minorversion "${sdl_minorversion_tmp}")
-        string(REGEX MATCH "([0-9]+)" sdl_patchversion "${sdl_patchversion_tmp}")
-        set(SDL_VERSION "${sdl_majorversion}.${sdl_minorversion}.${sdl_patchversion}")
-    endif()
-endif()
-
-mark_as_advanced(sdlversion_h sdl_majorversion sdl_minorversion sdl_patchversion)
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake_modules/FindSDL2_image.cmake	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,88 @@
+# - Locate SDL2_image library
+# This module defines:
+#  SDL2_IMAGE_LIBRARIES, the name of the library to link against
+#  SDL2_IMAGE_INCLUDE_DIRS, where to find the headers
+#  SDL2_IMAGE_FOUND, if false, do not try to link against
+#  SDL2_IMAGE_VERSION_STRING - human-readable string containing the version of SDL2_image
+#
+# For backward compatiblity the following variables are also set:
+#  SDL2IMAGE_LIBRARY (same value as SDL2_IMAGE_LIBRARIES)
+#  SDL2IMAGE_INCLUDE_DIR (same value as SDL2_IMAGE_INCLUDE_DIRS)
+#  SDL2IMAGE_FOUND (same value as SDL2_IMAGE_FOUND)
+#
+# $SDL2DIR is an environment variable that would
+# correspond to the ./configure --prefix=$SDL2DIR
+# used in building SDL2.
+#
+# Created by Eric Wing. This was influenced by the FindSDL2.cmake
+# module, but with modifications to recognize OS X frameworks and
+# additional Unix paths (FreeBSD, etc).
+
+#=============================================================================
+# Copyright 2005-2009 Kitware, Inc.
+# Copyright 2012 Benjamin Eikel
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+if(NOT SDL2_IMAGE_INCLUDE_DIR AND SDL2IMAGE_INCLUDE_DIR)
+  set(SDL2_IMAGE_INCLUDE_DIR ${SDL2IMAGE_INCLUDE_DIR} CACHE PATH "directory cache
+entry initialized from old variable name")
+endif()
+find_path(SDL2_IMAGE_INCLUDE_DIR SDL_image.h
+  HINTS
+    ENV SDL2IMAGEDIR
+    ENV SDL2DIR
+  PATH_SUFFIXES include/SDL2 include
+)
+
+if(NOT SDL2_IMAGE_LIBRARY AND SDL2IMAGE_LIBRARY)
+  set(SDL2_IMAGE_LIBRARY ${SDL2IMAGE_LIBRARY} CACHE FILEPATH "file cache entry
+initialized from old variable name")
+endif()
+find_library(SDL2_IMAGE_LIBRARY
+  NAMES SDL2_image
+  HINTS
+    ENV SDL2IMAGEDIR
+    ENV SDL2DIR
+  PATH_SUFFIXES lib
+)
+
+if(SDL2_IMAGE_INCLUDE_DIR AND EXISTS "${SDL2_IMAGE_INCLUDE_DIR}/SDL2_image.h")
+  file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL2_image.h" SDL2_IMAGE_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL2_IMAGE_MAJOR_VERSION[ \t]+[0-9]+$")
+  file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL2_image.h" SDL2_IMAGE_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL2_IMAGE_MINOR_VERSION[ \t]+[0-9]+$")
+  file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL2_image.h" SDL2_IMAGE_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL2_IMAGE_PATCHLEVEL[ \t]+[0-9]+$")
+  string(REGEX REPLACE "^#define[ \t]+SDL2_IMAGE_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_MAJOR "${SDL2_IMAGE_VERSION_MAJOR_LINE}")
+  string(REGEX REPLACE "^#define[ \t]+SDL2_IMAGE_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_MINOR "${SDL2_IMAGE_VERSION_MINOR_LINE}")
+  string(REGEX REPLACE "^#define[ \t]+SDL2_IMAGE_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_PATCH "${SDL2_IMAGE_VERSION_PATCH_LINE}")
+  set(SDL2_IMAGE_VERSION_STRING ${SDL2_IMAGE_VERSION_MAJOR}.${SDL2_IMAGE_VERSION_MINOR}.${SDL2_IMAGE_VERSION_PATCH})
+  unset(SDL2_IMAGE_VERSION_MAJOR_LINE)
+  unset(SDL2_IMAGE_VERSION_MINOR_LINE)
+  unset(SDL2_IMAGE_VERSION_PATCH_LINE)
+  unset(SDL2_IMAGE_VERSION_MAJOR)
+  unset(SDL2_IMAGE_VERSION_MINOR)
+  unset(SDL2_IMAGE_VERSION_PATCH)
+endif()
+
+set(SDL2_IMAGE_LIBRARIES ${SDL2_IMAGE_LIBRARY})
+set(SDL2_IMAGE_INCLUDE_DIRS ${SDL2_IMAGE_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_image
+                                  REQUIRED_VARS SDL2_IMAGE_LIBRARIES SDL2_IMAGE_INCLUDE_DIRS
+                                  VERSION_VAR SDL2_IMAGE_VERSION_STRING)
+
+# for backward compatiblity
+set(SDL2IMAGE_LIBRARY ${SDL2_IMAGE_LIBRARIES})
+set(SDL2IMAGE_INCLUDE_DIR ${SDL2_IMAGE_INCLUDE_DIRS})
+set(SDL2IMAGE_FOUND ${SDL2_IMAGE_FOUND})
+
+mark_as_advanced(SDL2_IMAGE_LIBRARY SDL2_IMAGE_INCLUDE_DIR)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake_modules/FindSDL2_mixer.cmake	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,88 @@
+# - Locate SDL2_mixer library
+# This module defines:
+#  SDL2_MIXER_LIBRARIES, the name of the library to link against
+#  SDL2_MIXER_INCLUDE_DIRS, where to find the headers
+#  SDL2_MIXER_FOUND, if false, do not try to link against
+#  SDL2_MIXER_VERSION_STRING - human-readable string containing the version of SDL2_mixer
+#
+# For backward compatiblity the following variables are also set:
+#  SDL2MIXER_LIBRARY (same value as SDL2_MIXER_LIBRARIES)
+#  SDL2MIXER_INCLUDE_DIR (same value as SDL2_MIXER_INCLUDE_DIRS)
+#  SDL2MIXER_FOUND (same value as SDL2_MIXER_FOUND)
+#
+# $SDL2DIR is an environment variable that would
+# correspond to the ./configure --prefix=$SDL2DIR
+# used in building SDL2.
+#
+# Created by Eric Wing. This was influenced by the FindSDL2.cmake
+# module, but with modifications to recognize OS X frameworks and
+# additional Unix paths (FreeBSD, etc).
+
+#=============================================================================
+# Copyright 2005-2009 Kitware, Inc.
+# Copyright 2012 Benjamin Eikel
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+if(NOT SDL2_MIXER_INCLUDE_DIR AND SDL2MIXER_INCLUDE_DIR)
+  set(SDL2_MIXER_INCLUDE_DIR ${SDL2MIXER_INCLUDE_DIR} CACHE PATH "directory cache
+entry initialized from old variable name")
+endif()
+find_path(SDL2_MIXER_INCLUDE_DIR SDL_mixer.h
+  HINTS
+    ENV SDL2MIXERDIR
+    ENV SDL2DIR
+  PATH_SUFFIXES include/SDL2 include
+)
+
+if(NOT SDL2_MIXER_LIBRARY AND SDL2MIXER_LIBRARY)
+  set(SDL2_MIXER_LIBRARY ${SDL2MIXER_LIBRARY} CACHE FILEPATH "file cache entry
+initialized from old variable name")
+endif()
+find_library(SDL2_MIXER_LIBRARY
+  NAMES SDL2_mixer
+  HINTS
+    ENV SDL2MIXERDIR
+    ENV SDL2DIR
+  PATH_SUFFIXES lib
+)
+
+if(SDL2_MIXER_INCLUDE_DIR AND EXISTS "${SDL2_MIXER_INCLUDE_DIR}/SDL2_mixer.h")
+  file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL2_mixer.h" SDL2_MIXER_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL2_MIXER_MAJOR_VERSION[ \t]+[0-9]+$")
+  file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL2_mixer.h" SDL2_MIXER_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL2_MIXER_MINOR_VERSION[ \t]+[0-9]+$")
+  file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL2_mixer.h" SDL2_MIXER_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL2_MIXER_PATCHLEVEL[ \t]+[0-9]+$")
+  string(REGEX REPLACE "^#define[ \t]+SDL2_MIXER_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_MAJOR "${SDL2_MIXER_VERSION_MAJOR_LINE}")
+  string(REGEX REPLACE "^#define[ \t]+SDL2_MIXER_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_MINOR "${SDL2_MIXER_VERSION_MINOR_LINE}")
+  string(REGEX REPLACE "^#define[ \t]+SDL2_MIXER_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_PATCH "${SDL2_MIXER_VERSION_PATCH_LINE}")
+  set(SDL2_MIXER_VERSION_STRING ${SDL2_MIXER_VERSION_MAJOR}.${SDL2_MIXER_VERSION_MINOR}.${SDL2_MIXER_VERSION_PATCH})
+  unset(SDL2_MIXER_VERSION_MAJOR_LINE)
+  unset(SDL2_MIXER_VERSION_MINOR_LINE)
+  unset(SDL2_MIXER_VERSION_PATCH_LINE)
+  unset(SDL2_MIXER_VERSION_MAJOR)
+  unset(SDL2_MIXER_VERSION_MINOR)
+  unset(SDL2_MIXER_VERSION_PATCH)
+endif()
+
+set(SDL2_MIXER_LIBRARIES ${SDL2_MIXER_LIBRARY})
+set(SDL2_MIXER_INCLUDE_DIRS ${SDL2_MIXER_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_mixer
+                                  REQUIRED_VARS SDL2_MIXER_LIBRARIES SDL2_MIXER_INCLUDE_DIRS
+                                  VERSION_VAR SDL2_MIXER_VERSION_STRING)
+
+# for backward compatiblity
+set(SDL2MIXER_LIBRARY ${SDL2_MIXER_LIBRARIES})
+set(SDL2MIXER_INCLUDE_DIR ${SDL2_MIXER_INCLUDE_DIRS})
+set(SDL2MIXER_FOUND ${SDL2_MIXER_FOUND})
+
+mark_as_advanced(SDL2_MIXER_LIBRARY SDL2_MIXER_INCLUDE_DIR)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake_modules/FindSDL2_net.cmake	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,88 @@
+# - Locate SDL2_net library
+# This module defines:
+#  SDL2_NET_LIBRARIES, the name of the library to link against
+#  SDL2_NET_INCLUDE_DIRS, where to find the headers
+#  SDL2_NET_FOUND, if false, do not try to link against
+#  SDL2_NET_VERSION_STRING - human-readable string containing the version of SDL2_net
+#
+# For backward compatiblity the following variables are also set:
+#  SDL2NET_LIBRARY (same value as SDL2_NET_LIBRARIES)
+#  SDL2NET_INCLUDE_DIR (same value as SDL2_NET_INCLUDE_DIRS)
+#  SDL2NET_FOUND (same value as SDL2_NET_FOUND)
+#
+# $SDL2DIR is an environment variable that would
+# correspond to the ./configure --prefix=$SDL2DIR
+# used in building SDL2.
+#
+# Created by Eric Wing. This was influenced by the FindSDL2.cmake
+# module, but with modifications to recognize OS X frameworks and
+# additional Unix paths (FreeBSD, etc).
+
+#=============================================================================
+# Copyright 2005-2009 Kitware, Inc.
+# Copyright 2012 Benjamin Eikel
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+if(NOT SDL2_NET_INCLUDE_DIR AND SDL2NET_INCLUDE_DIR)
+  set(SDL2_NET_INCLUDE_DIR ${SDL2NET_INCLUDE_DIR} CACHE PATH "directory cache
+entry initialized from old variable name")
+endif()
+find_path(SDL2_NET_INCLUDE_DIR SDL_net.h
+  HINTS
+    ENV SDL2NETDIR
+    ENV SDL2DIR
+  PATH_SUFFIXES include/SDL2 include
+)
+
+if(NOT SDL2_NET_LIBRARY AND SDL2NET_LIBRARY)
+  set(SDL2_NET_LIBRARY ${SDL2NET_LIBRARY} CACHE FILEPATH "file cache entry
+initialized from old variable name")
+endif()
+find_library(SDL2_NET_LIBRARY
+  NAMES SDL2_net
+  HINTS
+    ENV SDL2NETDIR
+    ENV SDL2DIR
+  PATH_SUFFIXES lib
+)
+
+if(SDL2_NET_INCLUDE_DIR AND EXISTS "${SDL2_NET_INCLUDE_DIR}/SDL2_net.h")
+  file(STRINGS "${SDL2_NET_INCLUDE_DIR}/SDL2_net.h" SDL2_NET_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL2_NET_MAJOR_VERSION[ \t]+[0-9]+$")
+  file(STRINGS "${SDL2_NET_INCLUDE_DIR}/SDL2_net.h" SDL2_NET_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL2_NET_MINOR_VERSION[ \t]+[0-9]+$")
+  file(STRINGS "${SDL2_NET_INCLUDE_DIR}/SDL2_net.h" SDL2_NET_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL2_NET_PATCHLEVEL[ \t]+[0-9]+$")
+  string(REGEX REPLACE "^#define[ \t]+SDL2_NET_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_NET_VERSION_MAJOR "${SDL2_NET_VERSION_MAJOR_LINE}")
+  string(REGEX REPLACE "^#define[ \t]+SDL2_NET_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_NET_VERSION_MINOR "${SDL2_NET_VERSION_MINOR_LINE}")
+  string(REGEX REPLACE "^#define[ \t]+SDL2_NET_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_NET_VERSION_PATCH "${SDL2_NET_VERSION_PATCH_LINE}")
+  set(SDL2_NET_VERSION_STRING ${SDL2_NET_VERSION_MAJOR}.${SDL2_NET_VERSION_MINOR}.${SDL2_NET_VERSION_PATCH})
+  unset(SDL2_NET_VERSION_MAJOR_LINE)
+  unset(SDL2_NET_VERSION_MINOR_LINE)
+  unset(SDL2_NET_VERSION_PATCH_LINE)
+  unset(SDL2_NET_VERSION_MAJOR)
+  unset(SDL2_NET_VERSION_MINOR)
+  unset(SDL2_NET_VERSION_PATCH)
+endif()
+
+set(SDL2_NET_LIBRARIES ${SDL2_NET_LIBRARY})
+set(SDL2_NET_INCLUDE_DIRS ${SDL2_NET_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_net
+                                  REQUIRED_VARS SDL2_NET_LIBRARIES SDL2_NET_INCLUDE_DIRS
+                                  VERSION_VAR SDL2_NET_VERSION_STRING)
+
+# for backward compatiblity
+set(SDL2NET_LIBRARY ${SDL2_NET_LIBRARIES})
+set(SDL2NET_INCLUDE_DIR ${SDL2_NET_INCLUDE_DIRS})
+set(SDL2NET_FOUND ${SDL2_NET_FOUND})
+
+mark_as_advanced(SDL2_NET_LIBRARY SDL2_NET_INCLUDE_DIR)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake_modules/FindSDL2_ttf.cmake	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,88 @@
+# - Locate SDL2_ttf library
+# This module defines:
+#  SDL2_TTF_LIBRARIES, the name of the library to link against
+#  SDL2_TTF_INCLUDE_DIRS, where to find the headers
+#  SDL2_TTF_FOUND, if false, do not try to link against
+#  SDL2_TTF_VERSION_STRING - human-readable string containing the version of SDL2_ttf
+#
+# For backward compatiblity the following variables are also set:
+#  SDL2TTF_LIBRARY (same value as SDL2_TTF_LIBRARIES)
+#  SDL2TTF_INCLUDE_DIR (same value as SDL2_TTF_INCLUDE_DIRS)
+#  SDL2TTF_FOUND (same value as SDL2_TTF_FOUND)
+#
+# $SDL2DIR is an environment variable that would
+# correspond to the ./configure --prefix=$SDL2DIR
+# used in building SDL2.
+#
+# Created by Eric Wing. This was influenced by the FindSDL2.cmake
+# module, but with modifications to recognize OS X frameworks and
+# additional Unix paths (FreeBSD, etc).
+
+#=============================================================================
+# Copyright 2005-2009 Kitware, Inc.
+# Copyright 2012 Benjamin Eikel
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+if(NOT SDL2_TTF_INCLUDE_DIR AND SDL2TTF_INCLUDE_DIR)
+  set(SDL2_TTF_INCLUDE_DIR ${SDL2TTF_INCLUDE_DIR} CACHE PATH "directory cache
+entry initialized from old variable name")
+endif()
+find_path(SDL2_TTF_INCLUDE_DIR SDL_ttf.h
+  HINTS
+    ENV SDL2TTFDIR
+    ENV SDL2DIR
+  PATH_SUFFIXES include/SDL2 include
+)
+
+if(NOT SDL2_TTF_LIBRARY AND SDL2TTF_LIBRARY)
+  set(SDL2_TTF_LIBRARY ${SDL2TTF_LIBRARY} CACHE FILEPATH "file cache entry
+initialized from old variable name")
+endif()
+find_library(SDL2_TTF_LIBRARY
+  NAMES SDL2_ttf
+  HINTS
+    ENV SDL2TTFDIR
+    ENV SDL2DIR
+  PATH_SUFFIXES lib
+)
+
+if(SDL2_TTF_INCLUDE_DIR AND EXISTS "${SDL2_TTF_INCLUDE_DIR}/SDL2_ttf.h")
+  file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL2_ttf.h" SDL2_TTF_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL2_TTF_MAJOR_VERSION[ \t]+[0-9]+$")
+  file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL2_ttf.h" SDL2_TTF_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL2_TTF_MINOR_VERSION[ \t]+[0-9]+$")
+  file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL2_ttf.h" SDL2_TTF_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL2_TTF_PATCHLEVEL[ \t]+[0-9]+$")
+  string(REGEX REPLACE "^#define[ \t]+SDL2_TTF_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_MAJOR "${SDL2_TTF_VERSION_MAJOR_LINE}")
+  string(REGEX REPLACE "^#define[ \t]+SDL2_TTF_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_MINOR "${SDL2_TTF_VERSION_MINOR_LINE}")
+  string(REGEX REPLACE "^#define[ \t]+SDL2_TTF_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_PATCH "${SDL2_TTF_VERSION_PATCH_LINE}")
+  set(SDL2_TTF_VERSION_STRING ${SDL2_TTF_VERSION_MAJOR}.${SDL2_TTF_VERSION_MINOR}.${SDL2_TTF_VERSION_PATCH})
+  unset(SDL2_TTF_VERSION_MAJOR_LINE)
+  unset(SDL2_TTF_VERSION_MINOR_LINE)
+  unset(SDL2_TTF_VERSION_PATCH_LINE)
+  unset(SDL2_TTF_VERSION_MAJOR)
+  unset(SDL2_TTF_VERSION_MINOR)
+  unset(SDL2_TTF_VERSION_PATCH)
+endif()
+
+set(SDL2_TTF_LIBRARIES ${SDL2_TTF_LIBRARY})
+set(SDL2_TTF_INCLUDE_DIRS ${SDL2_TTF_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_ttf
+                                  REQUIRED_VARS SDL2_TTF_LIBRARIES SDL2_TTF_INCLUDE_DIRS
+                                  VERSION_VAR SDL2_TTF_VERSION_STRING)
+
+# for backward compatiblity
+set(SDL2TTF_LIBRARY ${SDL2_TTF_LIBRARIES})
+set(SDL2TTF_INCLUDE_DIR ${SDL2_TTF_INCLUDE_DIRS})
+set(SDL2TTF_FOUND ${SDL2_TTF_FOUND})
+
+mark_as_advanced(SDL2_TTF_LIBRARY SDL2_TTF_INCLUDE_DIR)
--- a/cmake_modules/paths.cmake	Tue Sep 08 19:20:58 2015 +0300
+++ b/cmake_modules/paths.cmake	Mon Nov 16 22:57:24 2015 +0300
@@ -15,7 +15,7 @@
 #resource paths
 if(UNIX AND NOT APPLE)
     set(target_binary_install_dir "bin" CACHE PATH "install dest for binaries")
-    set(target_library_install_dir "lib" CACHE PATH "install dest for libs")
+    set(target_library_install_dir "lib${LIB_SUFFIX}" CACHE PATH "install dest for libs")
 
     string(SUBSTRING "${DATA_INSTALL_DIR}" 0 1 sharepath_start)
     if(${sharepath_start} MATCHES "/")
--- a/gameServer/Actions.hs	Tue Sep 08 19:20:58 2015 +0300
+++ b/gameServer/Actions.hs	Mon Nov 16 22:57:24 2015 +0300
@@ -744,10 +744,6 @@
 
     blackList <- liftM (map (recordFileName . fromJust . checkInfo) . filter (isJust . checkInfo)) allClientsS
 
-    readyCheckersIds <- io $ do
-        allci <- allClientsM rnc
-        filterM (client'sM rnc (isJust . checkInfo)) allci
-
     (cinfo, l) <- io $ loadReplay (fromIntegral p) blackList
     when (isJust cinfo) $
         mapM_ processAction [
@@ -757,15 +753,16 @@
 
 
 processAction (CheckFailed msg) = do
-    Just (CheckInfo fileName _) <- client's checkInfo
+    Just (CheckInfo fileName _ _) <- client's checkInfo
     io $ moveFailedRecord fileName
 
 
 processAction (CheckSuccess info) = do
-    Just (CheckInfo fileName teams) <- client's checkInfo
+    Just (CheckInfo fileName teams gameDetails) <- client's checkInfo
     p <- client's clientProto
     si <- gets serverInfo
-    io $ writeChan (dbQueries si) $ StoreAchievements p (B.pack fileName) (map toPair teams) info
+    when (isJust gameDetails)
+        $ io $ writeChan (dbQueries si) $ StoreAchievements p (B.pack fileName) (map toPair teams) (fromJust gameDetails) info
     io $ moveCheckedRecord fileName
     where
         toPair t = (teamname t, teamowner t)
--- a/gameServer/CoreTypes.hs	Tue Sep 08 19:20:58 2015 +0300
+++ b/gameServer/CoreTypes.hs	Mon Nov 16 22:57:24 2015 +0300
@@ -16,7 +16,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  \-}
 
-{-# LANGUAGE CPP, OverloadedStrings, DeriveDataTypeable #-}
+{-# LANGUAGE CPP, OverloadedStrings, DeriveDataTypeable, GeneralizedNewtypeDeriving #-}
 module CoreTypes where
 
 import Control.Concurrent
@@ -119,7 +119,8 @@
     CheckInfo
     {
         recordFileName :: String,
-        recordTeams :: [TeamInfo]
+        recordTeams :: [TeamInfo],
+        details :: Maybe GameDetails
     }
 
 data ClientInfo =
@@ -303,8 +304,8 @@
     ServerInfo
         True
         "<h2><p align=center><a href=\"http://www.hedgewars.org/\">http://www.hedgewars.org/</a></p></h2>"
-        "<font color=yellow><h3 align=center>Hedgewars 0.9.19 is out! Please update.</h3><p align=center><a href=http://hedgewars.org/download.html>Download page here</a></font>"
-        47 -- latestReleaseVersion
+        "<font color=yellow><h3 align=center>Hedgewars 0.9.22 is out! Please update.</h3><p align=center><a href=http://hedgewars.org/download.html>Download page here</a></font>"
+        51 -- latestReleaseVersion
         41 -- earliestCompatibleVersion
         46631
         ""
@@ -345,10 +346,21 @@
     CheckAccount ClientIndex Int B.ByteString B.ByteString
     | ClearCache
     | SendStats Int Int
-    | StoreAchievements Word16 B.ByteString [(B.ByteString, B.ByteString)] [B.ByteString]
+    | StoreAchievements Word16 B.ByteString [(B.ByteString, B.ByteString)] GameDetails [B.ByteString]
     | GetReplayName ClientIndex Int B.ByteString
     deriving (Show, Read)
 
+data GameDetails =
+    GameDetails {
+        gameScript :: B.ByteString
+        , infRope
+        , isVamp
+        , infAttacks :: Bool
+    } deriving (Show, Read)
+
+instance NFData GameDetails where
+    rnf (GameDetails a b c d) = a `deepseq` b `deepseq` c `deepseq` d `deepseq` ()
+
 data CoreMessage =
     Accept ClientInfo
     | ClientMessage (ClientIndex, [B.ByteString])
--- a/gameServer/EngineInteraction.hs	Tue Sep 08 19:20:58 2015 +0300
+++ b/gameServer/EngineInteraction.hs	Mon Nov 16 22:57:24 2015 +0300
@@ -100,8 +100,8 @@
         -> Map.Map B.ByteString B.ByteString
         -> Map.Map B.ByteString [B.ByteString]
         -> [B.ByteString]
-        -> [B.ByteString]
-replayToDemo ti mParams prms msgs = if not sane then [] else concat [
+        -> (Maybe GameDetails, [B.ByteString])
+replayToDemo ti mParams prms msgs = if not sane then (Nothing, []) else (Just $ GameDetails scriptName infRopes vamp infattacks, concat [
         [em "TD"]
         , maybeScript
         , maybeMap
@@ -117,7 +117,7 @@
         , concatMap teamSetup ti
         , msgs
         , [em "!"]
-        ]
+        ])
     where
         keys1, keys2 :: Set.Set B.ByteString
         keys1 = Set.fromList ["FEATURE_SIZE", "MAP", "MAPGEN", "MAZE_SIZE", "SEED", "TEMPLATE"]
@@ -126,8 +126,10 @@
             && Set.null (keys2 Set.\\ Map.keysSet prms)
             && (not . null . drop 41 $ scheme)
             && (not . null . tail $ prms Map.! "AMMO")
+            && ((B.length . head . tail $ prms Map.! "AMMO") > 200)
         mapGenTypes = ["+rnd+", "+maze+", "+drawn+", "+perlin+"]
-        maybeScript = let s = head . fromMaybe ["Normal"] $ Map.lookup "SCRIPT" prms in if s == "Normal" then [] else [eml ["escript Scripts/Multiplayer/", s, ".lua"]]
+        scriptName = head . fromMaybe ["Normal"] $ Map.lookup "SCRIPT" prms
+        maybeScript = let s = scriptName in if s == "Normal" then [] else [eml ["escript Scripts/Multiplayer/", spaces2Underlining s, ".lua"]]
         maybeMap = let m = mParams Map.! "MAP" in if m `elem` mapGenTypes then [] else [eml ["emap ", m]]
         scheme = tail $ prms Map.! "SCHEME"
         mapgen = mParams Map.! "MAPGEN"
@@ -161,6 +163,10 @@
                             ])
                         $ hedgehogs t
                         )
+        infRopes = ammoStr `B.index` 7  == '9'
+        vamp = gameFlags .&. 0x00000200 /= 0
+        infattacks = gameFlags .&. 0x00100000 /= 0
+        spaces2Underlining = B.map (\c -> if c == ' ' then '_' else c)
 
 drawnMapData :: B.ByteString -> [B.ByteString]
 drawnMapData =
@@ -190,6 +196,7 @@
     , ("e$minesnum", 1)
     , ("e$minedudpct", 1)
     , ("e$explosives", 1)
+    , ("e$airmines", 1)
     , ("e$healthprob", 1)
     , ("e$hcaseamount", 1)
     , ("e$waterrise", 1)
--- a/gameServer/OfficialServer/GameReplayStore.hs	Tue Sep 08 19:20:58 2015 +0300
+++ b/gameServer/OfficialServer/GameReplayStore.hs	Mon Nov 16 22:57:24 2015 +0300
@@ -16,7 +16,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  \-}
 
-{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE ScopedTypeVariables, OverloadedStrings #-}
 module OfficialServer.GameReplayStore where
 
 import Data.Time
@@ -38,13 +38,13 @@
 
 pickReplayFile :: Int -> [String] -> IO String
 pickReplayFile p blackList = do
-    files <- liftM (filter (\f -> sameProto f && notBlacklisted f)) $ getDirectoryContents "replays"
+    files <- liftM (filter (\f -> sameProto f && notBlacklisted ("replays/" ++ f))) $ getDirectoryContents "replays"
     if (not $ null files) then
         return $ "replays/" ++ head files
         else
         return ""
     where
-        sameProto = (isSuffixOf ('.' : show p))
+        sameProto = isSuffixOf ('.' : show p)
         notBlacklisted = flip notElem blackList
 
 saveReplay :: RoomInfo -> IO ()
@@ -70,11 +70,12 @@
     where
         loadFile :: String -> IO (Maybe CheckInfo, [B.ByteString])
         loadFile fileName = E.handle (\(e :: SomeException) ->
-                    warningM "REPLAYS" ("Problems reading " ++ fileName ++ ": " ++ show e) >> return (Just $ CheckInfo fileName [], [])) $ do
+                    warningM "REPLAYS" ("Problems reading " ++ fileName ++ ": " ++ show e) >> return (Just $ CheckInfo fileName [] Nothing, [])) $ do
             (teams, params1, params2, roundMsgs) <- liftM read $ readFile fileName
-            return $ (
-                Just (CheckInfo fileName teams)
-                , let d = replayToDemo teams (Map.fromList params1) (Map.fromList params2) (reverse roundMsgs) in d `deepseq` d
+            let d = replayToDemo teams (Map.fromList params1) (Map.fromList params2) (reverse roundMsgs)
+            d `deepseq` return $ (
+                Just (CheckInfo fileName teams (fst d))
+                , snd d
                 )
 
 moveFailedRecord :: String -> IO ()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gameServer/OfficialServer/Glicko2.hs	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,70 @@
+{-
+    Glicko2, as described in http://www.glicko.net/glicko/glicko2.pdf
+-}
+
+module OfficialServer.Glicko2 where
+
+data RatingData = RatingData {
+        ratingValue
+        , rD
+        , volatility :: Double
+    }
+data GameData = GameData {
+        opponentRating :: RatingData,
+        gameScore :: Double
+    }
+
+τ, ε :: Double
+τ = 0.2
+ε = 0.000001
+
+g_φ :: Double -> Double
+g_φ φ = 1 / sqrt (1 + 3 * φ^2 / pi^2)
+
+calcE :: RatingData -> GameData -> (Double, Double, Double)
+calcE oldRating (GameData oppRating s) = (
+    1 / (1 + exp (g_φᵢ * (μᵢ - μ)))
+    , g_φᵢ
+    , s
+    )
+    where
+        μ = (ratingValue oldRating - 1500) / 173.7178
+        φ = rD oldRating / 173.7178
+        μᵢ = (ratingValue oppRating - 1500) / 173.7178
+        φᵢ = rD oppRating / 173.7178
+        g_φᵢ = g_φ φᵢ
+
+
+calcNewRating :: RatingData -> [GameData] -> (Int, RatingData)
+calcNewRating oldRating [] = (0, RatingData (ratingValue oldRating) (173.7178 * sqrt (φ ^ 2 + σ ^ 2)) σ)
+    where
+        φ = rD oldRating / 173.7178
+        σ = volatility oldRating
+
+calcNewRating oldRating games = (length games, RatingData (173.7178 * μ' + 1500) (173.7178 * sqrt φ'sqr) σ')
+    where
+        _Es = map (calcE oldRating) games
+        υ = 1 / sum (map υ_p _Es)
+        υ_p (_Eᵢ, g_φᵢ, _) = g_φᵢ ^ 2 * _Eᵢ * (1 - _Eᵢ)
+        _Δ = υ * part1
+        part1 = sum (map _Δ_p _Es)
+        _Δ_p (_Eᵢ, g_φᵢ, sᵢ) = g_φᵢ * (sᵢ - _Eᵢ)
+
+        μ = (ratingValue oldRating - 1500) / 173.7178
+        φ = rD oldRating / 173.7178
+        σ = volatility oldRating
+
+        a = log (σ ^ 2)
+        f :: Double -> Double
+        f x = exp x * (_Δ ^ 2 - φ ^ 2 - υ - exp x) / 2 / (φ ^ 2 + υ + exp x) ^ 2 - (x - a) / τ ^ 2
+
+        _A = a
+        _B = if _Δ ^ 2 > φ ^ 2 + υ then log (_Δ ^ 2 - φ ^ 2 - υ) else head . dropWhile ((>) 0 . f) . map (\k -> a - k * τ) $ [1 ..]
+        fA = f _A
+        fB = f _B
+        σ' = (\(_A, _, _, _) -> exp (_A / 2)) . head . dropWhile (\(_A, _, _B, _) -> abs (_B - _A) > ε) $ iterate step5 (_A, fA, _B, fB)
+        step5 (_A, fA, _B, fB) = let _C = _A + (_A - _B) * fA / (fB - fA); fC = f _C in
+                                     if fC * fB < 0 then (_B, fB, _C, fC) else (_A, fA / 2, _C, fC)
+
+        φ'sqr = 1 / (1 / (φ ^ 2 + σ' ^ 2) + 1 / υ)
+        μ' = μ + φ'sqr * part1
--- a/gameServer/OfficialServer/checker.hs	Tue Sep 08 19:20:58 2015 +0300
+++ b/gameServer/OfficialServer/checker.hs	Mon Nov 16 22:57:24 2015 +0300
@@ -54,7 +54,7 @@
     deriving Show
 
 serverAddress = "netserver.hedgewars.org"
-protocolNumber = "49"
+protocolNumber = "51"
 
 getLines :: Handle -> IO [B.ByteString]
 getLines h = g
--- a/gameServer/OfficialServer/extdbinterface.hs	Tue Sep 08 19:20:58 2015 +0300
+++ b/gameServer/OfficialServer/extdbinterface.hs	Mon Nov 16 22:57:24 2015 +0300
@@ -28,9 +28,10 @@
 import Database.MySQL.Simple
 import Database.MySQL.Simple.QueryResults
 import Database.MySQL.Simple.Result
-import Data.List (lookup)
+import Data.List (lookup, elem)
 import qualified Data.ByteString.Char8 as B
 import Data.Word
+import Data.Int
 --------------------------
 import CoreTypes
 import Utils
@@ -50,6 +51,15 @@
     \ VALUES (?, (SELECT id FROM achievement_types WHERE name = ?), (SELECT uid FROM users WHERE name = ?), \
     \ ?, ?, ?, ?)"
 
+dbQueryGamesHistory =
+    "INSERT INTO rating_games (script, protocol, filename, time, vamp, ropes, infattacks) \
+    \ VALUES (?, ?, ?, ?, ?, ?, ?)"
+
+dbQueryGameId = "SELECT LAST_INSERT_ID()"
+
+dbQueryGamesHistoryPlaces = "INSERT INTO rating_players (userid, gameid, place) \
+    \ VALUES ((SELECT uid FROM users WHERE name = ?), ?, ?)"
+
 dbQueryReplayFilename = "SELECT filename FROM achievements WHERE id = ?"
 
 
@@ -83,36 +93,54 @@
 
         SendStats clients rooms ->
                 void $ execute dbConn dbQueryStats (clients, rooms)
-        StoreAchievements p fileName teams info ->
-            mapM_ (execute dbConn dbQueryAchievement) $ (parseStats p fileName teams) info
+        StoreAchievements p fileName teams g info ->
+            sequence_ $ parseStats dbConn p fileName teams g info
 
 
 --readTime = read . B.unpack . B.take 19 . B.drop 8
 readTime = B.take 19 . B.drop 8
 
 parseStats :: 
-    Word16 
+    Connection
+    -> Word16 
     -> B.ByteString 
     -> [(B.ByteString, B.ByteString)] 
-    -> [B.ByteString] 
-    -> [(B.ByteString, B.ByteString, B.ByteString, Int, B.ByteString, B.ByteString, Int)]
-parseStats p fileName teams = ps
+    -> GameDetails
+    -> [B.ByteString]
+    -> [IO Int64]
+parseStats dbConn p fileName teams (GameDetails script infRopes vamp infAttacks) = ps
     where
     time = readTime fileName
+    ps :: [B.ByteString] -> [IO Int64]
     ps [] = []
-    ps ("DRAW" : bs) = ps bs
-    ps ("WINNERS" : n : bs) = ps $ drop (readInt_ n) bs
-    ps ("ACHIEVEMENT" : typ : teamname : location : value : bs) =
+    ps ("DRAW" : bs) = execute dbConn dbQueryGamesHistory (script, (fromIntegral p) :: Int, fileName, time, vamp, infRopes, infAttacks)
+        : places (map drawParams teams)
+        : ps bs
+    ps ("WINNERS" : n : bs) = let winNum = readInt_ n in execute dbConn dbQueryGamesHistory (script, (fromIntegral p) :: Int, fileName, time, vamp, infRopes, infAttacks)
+        : places (map (placeParams (take winNum bs)) teams)
+        : ps (drop winNum bs)
+    ps ("ACHIEVEMENT" : typ : teamname : location : value : bs) = execute dbConn dbQueryAchievement
         ( time
         , typ
         , fromMaybe "" (lookup teamname teams)
-        , readInt_ value
+        , (readInt_ value) :: Int
         , fileName
         , location
-        , fromIntegral p
+        , (fromIntegral p) :: Int
         ) : ps bs
     ps (b:bs) = ps bs
-
+    drawParams t = (snd t, 0 :: Int)
+    placeParams winners t = (snd t, if (fst t) `elem` winners then 1 else 2 :: Int)
+    places :: [(B.ByteString, Int)] -> IO Int64
+    places params = do
+        res <- query_ dbConn dbQueryGameId
+        let gameId = case res of
+                [Only a] -> a
+                _ -> 0
+        mapM_ (execute dbConn dbQueryGamesHistoryPlaces . midInsert gameId) params
+        return 0
+    midInsert :: Int -> (a, b) -> (a, Int, b)
+    midInsert g (a, b) = (a, g, b)
 
 dbConnectionLoop mySQLConnectionInfo =
     Control.Exception.handle (\(e :: SomeException) -> hPutStrLn stderr $ show e) $
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gameServer/OfficialServer/updateRating.hs	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,103 @@
+{-# LANGUAGE ScopedTypeVariables, OverloadedStrings #-}
+module Main where
+
+import Data.Maybe
+import Data.TConfig
+import qualified Data.ByteString.Char8 as B
+import Database.MySQL.Simple
+import Database.MySQL.Simple.QueryResults
+import Database.MySQL.Simple.Result
+import Control.Monad
+import Control.Exception
+import System.IO
+import qualified  Data.Map as Map
+import Data.Time.Clock
+------
+import OfficialServer.Glicko2
+
+
+queryEpochDates = "SELECT epoch, todatetime, todatetime + INTERVAL 1 week FROM rating_epochs WHERE epoch = (SELECT MAX(epoch) FROM rating_epochs)"
+queryPreviousRatings = "SELECT v.userid, v.rating, v.rd, v.volatility FROM rating_values as v WHERE (v.epoch = (SELECT MAX(epoch) FROM rating_epochs))"
+queryGameResults =
+        "SELECT \
+        \     p.userid \
+        \     , p.place \
+        \     , COALESCE(vp.rating, 1500) \
+        \     , COALESCE(vp.rd, 350) \
+        \     , COALESCE(vp.volatility, 0.06) \
+        \     , COALESCE(vo.rating, 1500) \
+        \     , COALESCE(vo.rd, 350) \
+        \     , COALESCE(vo.volatility, 0.06) \
+        \ FROM \
+        \     (SELECT epoch, todatetime FROM rating_epochs WHERE epoch = (SELECT MAX(epoch) FROM rating_epochs)) as e \
+        \     JOIN rating_games as g ON (g.time BETWEEN e.todatetime AND e.todatetime + INTERVAL 1 WEEK - INTERVAL 1 SECOND) \
+        \     JOIN rating_players as p ON (p.gameid = g.id) \
+        \     JOIN rating_players as o ON (p.gameid = o.gameid AND p.userid <> o.userid AND (p.place = 0 OR (p.place <> o.place))) \
+        \     LEFT OUTER JOIN rating_values as vp ON (vp.epoch = e.epoch AND vp.userid = p.userid) \
+        \     LEFT OUTER JOIN rating_values as vo ON (vo.epoch = e.epoch AND vo.userid = o.userid) \
+        \ GROUP BY p.userid, p.gameid, p.place \
+        \ ORDER BY p.userid"
+insertNewRatings = "INSERT INTO rating_values (userid, epoch, rating, rd, volatility, games) VALUES (?, ?, ?, ?, ?, ?)"
+insertNewEpoch = "INSERT INTO rating_epochs (epoch, todatetime) VALUES (?, ?)"
+
+mergeRatingData :: Map.Map Int (RatingData, [GameData]) -> [(Int, (RatingData, [GameData]))] -> Map.Map Int (RatingData, [GameData])
+mergeRatingData m s = foldr (uncurry (Map.insertWith mf)) m s
+    where
+        mf (rd, gds) (_, gds2) = (rd, gds ++ gds2)
+
+calculateRatings dbConn = do
+    [(epochNum :: Int, fromDate :: UTCTime, toDate :: UTCTime)] <- query_ dbConn queryEpochDates
+    initRatingData <- (Map.fromList . map fromDBrating) `fmap` query_ dbConn queryPreviousRatings
+    gameData <- map fromGameResult `fmap` query_ dbConn queryGameResults
+    let mData = map getNewRating . Map.toList $ mergeRatingData initRatingData gameData
+    executeMany dbConn insertNewRatings $ map (toInsert epochNum) mData
+    execute dbConn insertNewEpoch (epochNum + 1, toDate)
+    return ()
+    where
+        toInsert e (i, (g, RatingData r rd v)) = (i, e + 1, r, rd, v, g)
+        getNewRating (a, d) = (a, uncurry calcNewRating d)
+        convPlace :: Int -> Double
+        convPlace 0 = 0.5
+        convPlace 1 = 1.0
+        convPlace 2 = 0.0
+        convPlace _ = error "Incorrect place value"
+        fromDBrating (a, b, c, d) = (a, (RatingData b c d, []))
+        fromGameResult (pid, place, prating, pRD, pvol, orating, oRD, ovol) =
+            (pid,
+                (RatingData prating pRD pvol
+                , [GameData (RatingData orating oRD ovol) $ convPlace place]))
+
+
+data DBConnectInfo = DBConnectInfo {
+    dbHost
+    , dbName
+    , dbLogin
+    , dbPassword :: B.ByteString
+    }
+
+cfgFileName :: String
+cfgFileName = "hedgewars-server.ini"
+
+
+readServerConfig :: ConnectInfo -> IO ConnectInfo
+readServerConfig ci = do
+    cfg <- readConfig cfgFileName
+    return $ ci{
+        connectHost = value "dbHost" cfg
+        , connectDatabase = value "dbName" cfg
+        , connectUser = value "dbLogin" cfg
+        , connectPassword = value "dbPassword" cfg
+    }
+    where
+        value n c = fromJust2 n $ getValue n c
+        fromJust2 n Nothing = error $ "Missing config entry " ++ n
+        fromJust2 _ (Just a) = a
+
+dbConnectionLoop mySQLConnectionInfo =
+    Control.Exception.handle (\(e :: SomeException) -> hPutStrLn stderr $ show e) $
+        bracket
+            (connect mySQLConnectionInfo)
+            close
+            calculateRatings
+
+main = readServerConfig defaultConnectInfo >>= dbConnectionLoop
--- a/gameServer/Utils.hs	Tue Sep 08 19:20:58 2015 +0300
+++ b/gameServer/Utils.hs	Mon Nov 16 22:57:24 2015 +0300
@@ -115,6 +115,8 @@
             , (48, "0.9.21-dev")
             , (49, "0.9.21")
             , (50, "0.9.22-dev")
+            , (51, "0.9.22")
+            , (52, "0.9.23-dev")
             ]
 
 askFromConsole :: B.ByteString -> IO B.ByteString
--- a/hedgewars/ArgParsers.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/ArgParsers.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -321,7 +321,7 @@
 var tmpInt: LongInt;
 begin
 
-    paramIndex:= 1;
+    paramIndex:= {$IFDEF HWLIBRARY}0{$ELSE}1{$ENDIF};
     paramTotal:= ParamCount; //-1 because pascal enumeration is inclusive
     
     WriteLn(stdout, 'total parameters: ' + inttostr(paramTotal));
--- a/hedgewars/CMakeLists.txt	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/CMakeLists.txt	Mon Nov 16 22:57:24 2015 +0300
@@ -1,8 +1,10 @@
-find_package(SDL1or2)
-find_package(SDL_image)
-find_package(SDL_net)
-find_package(SDL_ttf)
-find_package(SDL_mixer)
+enable_language(Pascal)
+
+find_package(SDL2 REQUIRED)
+find_package(SDL2_image REQUIRED)
+find_package(SDL2_net REQUIRED)
+find_package(SDL2_ttf REQUIRED)
+find_package(SDL2_mixer REQUIRED)
 
 include(CheckLibraryExists)
 include(${CMAKE_MODULE_PATH}/utils.cmake)
@@ -136,22 +138,16 @@
 
 #DEPENDECIES AND EXECUTABLES SECTION
 if(APPLE AND (NOT BUILD_ENGINE_LIBRARY))
-    #on OSX we need to provide the SDL_main() function when building as
-    #executable and the entry point too
-    add_subdirectory(sdlmain)
-    list(APPEND HW_LINK_LIBS SDLmain)
-    add_flag_append(CMAKE_Pascal_FLAGS "-k-lsdlmain")
-    add_flag_append(CMAKE_Pascal_FLAGS "-XMSDL_main")
     #OpenGL deps
     add_flag_append(CMAKE_Pascal_FLAGS "-k-framework -kCocoa")
     add_flag_append(CMAKE_Pascal_FLAGS "-k-framework -kOpenGL")
 
     #set the correct library or framework style depending on the main SDL
-    string(FIND "${SDL_LIBRARY}" "dylib" sdl_framework)
+    string(FIND "${SDL2_LIBRARY}" "dylib" sdl_framework)
     if(${sdl_framework} GREATER -1)
-        add_flag_append(CMAKE_Pascal_FLAGS "-k-lsdl -k-lsdl_image -k-lsdl_mixer -k-lsdl_ttf -k-lsdl_net")
+        add_flag_append(CMAKE_Pascal_FLAGS "-k-lsdl2 -k-lsdl2_image -k-lsdl2_mixer -k-lsdl2_ttf -k-lsdl2_net")
     else()
-        add_flag_append(CMAKE_Pascal_FLAGS "-k-framework -kSDL -k-framework -kSDL_image -k-framework -k SDL_mixer -k-framework -k SDL_net -k-framework -kSDL_net")
+        add_flag_append(CMAKE_Pascal_FLAGS "-k-framework -kSDL2 -k-framework -kSDL2_image -k-framework -kSDL2_mixer -k-framework -kSDL2_net -k-framework -kSDL2_net -k-framework -kSDL2_ttf")
     endif()
 endif()
 
@@ -159,8 +155,6 @@
     add_subdirectory(avwrapper)
     list(APPEND HW_LINK_LIBS avwrapper)
     add_definitions(-dUSE_VIDEO_RECORDING)
-    #only for SDL < 2, linking carried out by fpc
-    find_package_or_disable_msg(GLUT NOVIDEOREC "Video recording will not be built")
 endif()
 
 find_package_or_disable_msg(PNG NOPNG "Screenshots will be saved in BMP")
@@ -198,22 +192,6 @@
 list(APPEND HW_LINK_LIBS physlayer)
 
 
-#Mix_Init/Mix_Quit from SDL_mixer 1.2.10
-check_library_exists(${SDLMIXER_LIBRARY} Mix_Init "" HAVE_MIXINIT)
-if(HAVE_MIXINIT)
-    add_definitions(-dSDL_MIXER_NEWER)
-endif(HAVE_MIXINIT)
-
-#IMG_Init/IMG_Quit from SDL_image 1.2.8
-check_library_exists(${SDLIMAGE_LIBRARY} IMG_Init "" HAVE_IMGINIT)
-if(HAVE_IMGINIT)
-    add_definitions(-dSDL_IMAGE_NEWER)
-endif(HAVE_IMGINIT)
-
-if(${SDL_VERSION} VERSION_GREATER 1.3)
-    add_definitions(-dSDL2)
-endif()
-
 #opengl 2
 IF(GL2)
     add_definitions(-dGL2)
--- a/hedgewars/SDLh.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/SDLh.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -57,17 +57,17 @@
 (*  SDL  *)
 const
 {$IFDEF WIN32}
-    SDLLibName = 'SDL.dll';
-    SDL_TTFLibName = 'SDL_ttf.dll';
-    SDL_MixerLibName = 'SDL_mixer.dll';
-    SDL_ImageLibName = 'SDL_image.dll';
-    SDL_NetLibName = 'SDL_net.dll';
+    SDLLibName = 'SDL2.dll';
+    SDL_TTFLibName = 'SDL2_ttf.dll';
+    SDL_MixerLibName = 'SDL2_mixer.dll';
+    SDL_ImageLibName = 'SDL2_image.dll';
+    SDL_NetLibName = 'SDL2_net.dll';
 {$ELSE}
-    SDLLibName = 'libSDL';
-    SDL_TTFLibName = 'libSDL_ttf';
-    SDL_MixerLibName = 'libSDL_mixer';
-    SDL_ImageLibName = 'libSDL_image';
-    SDL_NetLibName = 'libSDL_net';
+    SDLLibName = 'libSDL2';
+    SDL_TTFLibName = 'libSDL2_ttf';
+    SDL_MixerLibName = 'libSDL2_mixer';
+    SDL_ImageLibName = 'libSDL2_image';
+    SDL_NetLibName = 'libSDL2_net';
 {$ENDIF}
 
 /////////////////////////////////////////////////////////////////
@@ -79,14 +79,9 @@
     SDL_INIT_AUDIO          = $00000010;
     SDL_INIT_VIDEO          = $00000020; // implies SDL_INIT_EVENTS (sdl2)
     SDL_INIT_JOYSTICK       = $00000200; // implies SDL_INIT_EVENTS (sdl2)
-{$IFDEF SDL2}
     SDL_INIT_HAPTIC         = $00001000;
     SDL_INIT_GAMECONTROLLER = $00002000; // implies SDL_INIT_JOYSTICK
     SDL_INIT_EVENTS         = $00004000;
-{$ELSE}
-    SDL_INIT_CDROM          = $00000100;
-    SDL_INIT_EVENTTHREAD    = $01000000;
-{$ENDIF}
     SDL_INIT_NOPARACHUTE    = $00100000;
     //SDL_INIT_EVERYTHING                // unsafe, init subsystems one at a time
 
@@ -100,7 +95,9 @@
     SDL_BUTTON_WHEELDOWN = 5;
 
 
-{$IFDEF SDL2}
+    SDL_TEXTEDITINGEVENT_TEXT_SIZE = 32;
+    SDL_TEXTINPUTEVENT_TEXT_SIZE   = 32;
+
     // SDL_Event types
     // pascal does not support unions as is, so we list here every possible event
     // and later associate a struct type each
@@ -193,39 +190,6 @@
     SDL_WINDOWEVENT_FOCUS_GAINED = 12;   //*< Window has gained keyboard focus
     SDL_WINDOWEVENT_FOCUS_LOST   = 13;   //*< Window has lost keyboard focus
     SDL_WINDOWEVENT_CLOSE        = 14;   //*< The window manager requests that the window be closed */
-{$ELSE}
-    // SDL_Event types
-    SDL_NOEVENT         = 0;
-    SDL_ACTIVEEVENT     = 1;
-    SDL_KEYDOWN         = 2;
-    SDL_KEYUP           = 3;
-    SDL_MOUSEMOTION     = 4;
-    SDL_MOUSEBUTTONDOWN = 5;
-    SDL_MOUSEBUTTONUP   = 6;
-    SDL_JOYAXISMOTION   = 7;
-    SDL_JOYBALLMOTION   = 8;
-    SDL_JOYHATMOTION    = 9;
-    SDL_JOYBUTTONDOWN   = 10;
-    SDL_JOYBUTTONUP     = 11;
-    SDL_QUITEV          = 12;
-    SDL_VIDEORESIZE     = 16;
-
-    // SDL_Surface flags
-    SDL_SWSURFACE   = $00000000;
-    SDL_HWSURFACE   = $00000001;
-    SDL_OPENGL      = $00000002;
-    SDL_ASYNCBLIT   = $00000004;
-    SDL_RESIZABLE   = $00000010;
-    SDL_NOFRAME     = $00000020;
-    SDL_HWACCEL     = $00000100;
-    SDL_SRCCOLORKEY = $00001000;
-    SDL_RLEACCEL    = $00004000;
-    SDL_SRCALPHA    = $00010000;
-    SDL_ANYFORMAT   = $00100000;
-    SDL_HWPALETTE   = $20000000;
-    SDL_DOUBLEBUF   = $40000000;
-    SDL_FULLSCREEN  = $80000000;
-{$ENDIF}
 
 {$IFDEF ENDIAN_LITTLE}
     RMask = $000000FF;
@@ -261,11 +225,13 @@
     KMOD_MODE   = $4000;
 
     {* SDL_mixer *}
-    MIX_MAX_VOLUME = 128;
-    MIX_INIT_FLAC  = $00000001;
-    MIX_INIT_MOD   = $00000002;
-    MIX_INIT_MP3   = $00000004;
-    MIX_INIT_OGG   = $00000008;
+    MIX_MAX_VOLUME      = 128;
+    MIX_INIT_FLAC       = $00000001;
+    MIX_INIT_MOD        = $00000002;
+    MIX_INIT_MODPLUG    = $00000004;
+    MIX_INIT_MP3        = $00000008;
+    MIX_INIT_OGG        = $00000010;
+    MIX_INIT_FLUIDSYNTH = $00000020;
 
     {* SDL_TTF *}
     TTF_STYLE_NORMAL = 0;
@@ -288,7 +254,8 @@
     IMG_INIT_PNG = $00000002;
     IMG_INIT_TIF = $00000004;
 
-    {* SDL_keysym *}
+    {* SDL_keycode *}
+    SDLK_UNKNOWN = 0;
     SDLK_BACKSPACE = 8;
     SDLK_RETURN    = 13;
     SDLK_ESCAPE    = 27;
@@ -309,6 +276,250 @@
     SDLK_PAGEUP    = 280;
     SDLK_PAGEDOWN  = 281;
 
+    // special keycodes (for modifier keys etc. will have this bit set)
+    SDLK_SCANCODE_MASK = (1 shl 30);
+
+    SDL_SCANCODE_UNKNOWN = 0;
+    SDL_SCANCODE_A = 4;
+    SDL_SCANCODE_B = 5;
+    SDL_SCANCODE_C = 6;
+    SDL_SCANCODE_D = 7;
+    SDL_SCANCODE_E = 8;
+    SDL_SCANCODE_F = 9;
+    SDL_SCANCODE_G = 10;
+    SDL_SCANCODE_H = 11;
+    SDL_SCANCODE_I = 12;
+    SDL_SCANCODE_J = 13;
+    SDL_SCANCODE_K = 14;
+    SDL_SCANCODE_L = 15;
+    SDL_SCANCODE_M = 16;
+    SDL_SCANCODE_N = 17;
+    SDL_SCANCODE_O = 18;
+    SDL_SCANCODE_P = 19;
+    SDL_SCANCODE_Q = 20;
+    SDL_SCANCODE_R = 21;
+    SDL_SCANCODE_S = 22;
+    SDL_SCANCODE_T = 23;
+    SDL_SCANCODE_U = 24;
+    SDL_SCANCODE_V = 25;
+    SDL_SCANCODE_W = 26;
+    SDL_SCANCODE_X = 27;
+    SDL_SCANCODE_Y = 28;
+    SDL_SCANCODE_Z = 29;
+    SDL_SCANCODE_1 = 30;
+    SDL_SCANCODE_2 = 31;
+    SDL_SCANCODE_3 = 32;
+    SDL_SCANCODE_4 = 33;
+    SDL_SCANCODE_5 = 34;
+    SDL_SCANCODE_6 = 35;
+    SDL_SCANCODE_7 = 36;
+    SDL_SCANCODE_8 = 37;
+    SDL_SCANCODE_9 = 38;
+    SDL_SCANCODE_0 = 39;
+    SDL_SCANCODE_RETURN = 40;
+    SDL_SCANCODE_ESCAPE = 41;
+    SDL_SCANCODE_BACKSPACE = 42;
+    SDL_SCANCODE_TAB = 43;
+    SDL_SCANCODE_SPACE = 44;
+    SDL_SCANCODE_MINUS = 45;
+    SDL_SCANCODE_EQUALS = 46;
+    SDL_SCANCODE_LEFTBRACKET = 47;
+    SDL_SCANCODE_RIGHTBRACKET = 48;
+    SDL_SCANCODE_BACKSLASH = 49;
+    SDL_SCANCODE_NONUSHASH = 50;
+    SDL_SCANCODE_SEMICOLON = 51;
+    SDL_SCANCODE_APOSTROPHE = 52;
+    SDL_SCANCODE_GRAVE = 53;
+    SDL_SCANCODE_COMMA = 54;
+    SDL_SCANCODE_PERIOD = 55;
+    SDL_SCANCODE_SLASH = 56;
+    SDL_SCANCODE_CAPSLOCK = 57;
+    SDL_SCANCODE_F1 = 58;
+    SDL_SCANCODE_F2 = 59;
+    SDL_SCANCODE_F3 = 60;
+    SDL_SCANCODE_F4 = 61;
+    SDL_SCANCODE_F5 = 62;
+    SDL_SCANCODE_F6 = 63;
+    SDL_SCANCODE_F7 = 64;
+    SDL_SCANCODE_F8 = 65;
+    SDL_SCANCODE_F9 = 66;
+    SDL_SCANCODE_F10 = 67;
+    SDL_SCANCODE_F11 = 68;
+    SDL_SCANCODE_F12 = 69;
+    SDL_SCANCODE_PRINTSCREEN = 70;
+    SDL_SCANCODE_SCROLLLOCK = 71;
+    SDL_SCANCODE_PAUSE = 72;
+    SDL_SCANCODE_INSERT = 73;
+    SDL_SCANCODE_HOME = 74;
+    SDL_SCANCODE_PAGEUP = 75;
+    SDL_SCANCODE_DELETE = 76;
+    SDL_SCANCODE_END = 77;
+    SDL_SCANCODE_PAGEDOWN = 78;
+    SDL_SCANCODE_RIGHT = 79;
+    SDL_SCANCODE_LEFT = 80;
+    SDL_SCANCODE_DOWN = 81;
+    SDL_SCANCODE_UP = 82;
+    SDL_SCANCODE_NUMLOCKCLEAR = 83;
+    SDL_SCANCODE_KP_DIVIDE = 84;
+    SDL_SCANCODE_KP_MULTIPLY = 85;
+    SDL_SCANCODE_KP_MINUS = 86;
+    SDL_SCANCODE_KP_PLUS = 87;
+    SDL_SCANCODE_KP_ENTER = 88;
+    SDL_SCANCODE_KP_1 = 89;
+    SDL_SCANCODE_KP_2 = 90;
+    SDL_SCANCODE_KP_3 = 91;
+    SDL_SCANCODE_KP_4 = 92;
+    SDL_SCANCODE_KP_5 = 93;
+    SDL_SCANCODE_KP_6 = 94;
+    SDL_SCANCODE_KP_7 = 95;
+    SDL_SCANCODE_KP_8 = 96;
+    SDL_SCANCODE_KP_9 = 97;
+    SDL_SCANCODE_KP_0 = 98;
+    SDL_SCANCODE_KP_PERIOD = 99;
+    SDL_SCANCODE_NONUSBACKSLASH = 100;
+    SDL_SCANCODE_APPLICATION = 101;
+    SDL_SCANCODE_POWER = 102;
+    SDL_SCANCODE_KP_EQUALS = 103;
+    SDL_SCANCODE_F13 = 104;
+    SDL_SCANCODE_F14 = 105;
+    SDL_SCANCODE_F15 = 106;
+    SDL_SCANCODE_F16 = 107;
+    SDL_SCANCODE_F17 = 108;
+    SDL_SCANCODE_F18 = 109;
+    SDL_SCANCODE_F19 = 110;
+    SDL_SCANCODE_F20 = 111;
+    SDL_SCANCODE_F21 = 112;
+    SDL_SCANCODE_F22 = 113;
+    SDL_SCANCODE_F23 = 114;
+    SDL_SCANCODE_F24 = 115;
+    SDL_SCANCODE_EXECUTE = 116;
+    SDL_SCANCODE_HELP = 117;
+    SDL_SCANCODE_MENU = 118;
+    SDL_SCANCODE_SELECT = 119;
+    SDL_SCANCODE_STOP = 120;
+    SDL_SCANCODE_AGAIN = 121;
+    SDL_SCANCODE_UNDO = 122;
+    SDL_SCANCODE_CUT = 123;
+    SDL_SCANCODE_COPY = 124;
+    SDL_SCANCODE_PASTE = 125;
+    SDL_SCANCODE_FIND = 126;
+    SDL_SCANCODE_MUTE = 127;
+    SDL_SCANCODE_VOLUMEUP = 128;
+    SDL_SCANCODE_VOLUMEDOWN = 129;
+    SDL_SCANCODE_KP_COMMA = 133;
+    SDL_SCANCODE_KP_EQUALSAS400 = 134;
+    SDL_SCANCODE_INTERNATIONAL1 = 135;
+    SDL_SCANCODE_INTERNATIONAL2 = 136;
+    SDL_SCANCODE_INTERNATIONAL3 = 137;
+    SDL_SCANCODE_INTERNATIONAL4 = 138;
+    SDL_SCANCODE_INTERNATIONAL5 = 139;
+    SDL_SCANCODE_INTERNATIONAL6 = 140;
+    SDL_SCANCODE_INTERNATIONAL7 = 141;
+    SDL_SCANCODE_INTERNATIONAL8 = 142;
+    SDL_SCANCODE_INTERNATIONAL9 = 143;
+    SDL_SCANCODE_LANG1 = 144; (*< Hangul/English toggle *)
+    SDL_SCANCODE_LANG2 = 145; (*< Hanja conversion *)
+    SDL_SCANCODE_LANG3 = 146; (*< Katakana *)
+    SDL_SCANCODE_LANG4 = 147; (*< Hiragana *)
+    SDL_SCANCODE_LANG5 = 148; (*< Zenkaku/Hankaku *)
+    SDL_SCANCODE_LANG6 = 149; (*< reserved *)
+    SDL_SCANCODE_LANG7 = 150; (*< reserved *)
+    SDL_SCANCODE_LANG8 = 151; (*< reserved *)
+    SDL_SCANCODE_LANG9 = 152; (*< reserved *)
+    SDL_SCANCODE_ALTERASE = 153;
+    SDL_SCANCODE_SYSREQ = 154;
+    SDL_SCANCODE_CANCEL = 155;
+    SDL_SCANCODE_CLEAR = 156;
+    SDL_SCANCODE_PRIOR = 157;
+    SDL_SCANCODE_RETURN2 = 158;
+    SDL_SCANCODE_SEPARATOR = 159;
+    SDL_SCANCODE_OUT = 160;
+    SDL_SCANCODE_OPER = 161;
+    SDL_SCANCODE_CLEARAGAIN = 162;
+    SDL_SCANCODE_CRSEL = 163;
+    SDL_SCANCODE_EXSEL = 164;
+    SDL_SCANCODE_KP_00 = 176;
+    SDL_SCANCODE_KP_000 = 177;
+    SDL_SCANCODE_THOUSANDSSEPARATOR = 178;
+    SDL_SCANCODE_DECIMALSEPARATOR = 179;
+    SDL_SCANCODE_CURRENCYUNIT = 180;
+    SDL_SCANCODE_CURRENCYSUBUNIT = 181;
+    SDL_SCANCODE_KP_LEFTPAREN = 182;
+    SDL_SCANCODE_KP_RIGHTPAREN = 183;
+    SDL_SCANCODE_KP_LEFTBRACE = 184;
+    SDL_SCANCODE_KP_RIGHTBRACE = 185;
+    SDL_SCANCODE_KP_TAB = 186;
+    SDL_SCANCODE_KP_BACKSPACE = 187;
+    SDL_SCANCODE_KP_A = 188;
+    SDL_SCANCODE_KP_B = 189;
+    SDL_SCANCODE_KP_C = 190;
+    SDL_SCANCODE_KP_D = 191;
+    SDL_SCANCODE_KP_E = 192;
+    SDL_SCANCODE_KP_F = 193;
+    SDL_SCANCODE_KP_XOR = 194;
+    SDL_SCANCODE_KP_POWER = 195;
+    SDL_SCANCODE_KP_PERCENT = 196;
+    SDL_SCANCODE_KP_LESS = 197;
+    SDL_SCANCODE_KP_GREATER = 198;
+    SDL_SCANCODE_KP_AMPERSAND = 199;
+    SDL_SCANCODE_KP_DBLAMPERSAND = 200;
+    SDL_SCANCODE_KP_VERTICALBAR = 201;
+    SDL_SCANCODE_KP_DBLVERTICALBAR = 202;
+    SDL_SCANCODE_KP_COLON = 203;
+    SDL_SCANCODE_KP_HASH = 204;
+    SDL_SCANCODE_KP_SPACE = 205;
+    SDL_SCANCODE_KP_AT = 206;
+    SDL_SCANCODE_KP_EXCLAM = 207;
+    SDL_SCANCODE_KP_MEMSTORE = 208;
+    SDL_SCANCODE_KP_MEMRECALL = 209;
+    SDL_SCANCODE_KP_MEMCLEAR = 210;
+    SDL_SCANCODE_KP_MEMADD = 211;
+    SDL_SCANCODE_KP_MEMSUBTRACT = 212;
+    SDL_SCANCODE_KP_MEMMULTIPLY = 213;
+    SDL_SCANCODE_KP_MEMDIVIDE = 214;
+    SDL_SCANCODE_KP_PLUSMINUS = 215;
+    SDL_SCANCODE_KP_CLEAR = 216;
+    SDL_SCANCODE_KP_CLEARENTRY = 217;
+    SDL_SCANCODE_KP_BINARY = 218;
+    SDL_SCANCODE_KP_OCTAL = 219;
+    SDL_SCANCODE_KP_DECIMAL = 220;
+    SDL_SCANCODE_KP_HEXADECIMAL = 221;
+    SDL_SCANCODE_LCTRL = 224;
+    SDL_SCANCODE_LSHIFT = 225;
+    SDL_SCANCODE_LALT = 226;
+    SDL_SCANCODE_LGUI = 227;
+    SDL_SCANCODE_RCTRL = 228;
+    SDL_SCANCODE_RSHIFT = 229;
+    SDL_SCANCODE_RALT = 230;
+    SDL_SCANCODE_RGUI = 231;
+    SDL_SCANCODE_MODE = 257;
+    SDL_SCANCODE_AUDIONEXT = 258;
+    SDL_SCANCODE_AUDIOPREV = 259;
+    SDL_SCANCODE_AUDIOSTOP = 260;
+    SDL_SCANCODE_AUDIOPLAY = 261;
+    SDL_SCANCODE_AUDIOMUTE = 262;
+    SDL_SCANCODE_MEDIASELECT = 263;
+    SDL_SCANCODE_WWW = 264;
+    SDL_SCANCODE_MAIL = 265;
+    SDL_SCANCODE_CALCULATOR = 266;
+    SDL_SCANCODE_COMPUTER = 267;
+    SDL_SCANCODE_AC_SEARCH = 268;
+    SDL_SCANCODE_AC_HOME = 269;
+    SDL_SCANCODE_AC_BACK = 270;
+    SDL_SCANCODE_AC_FORWARD = 271;
+    SDL_SCANCODE_AC_STOP = 272;
+    SDL_SCANCODE_AC_REFRESH = 273;
+    SDL_SCANCODE_AC_BOOKMARKS = 274;
+    SDL_SCANCODE_BRIGHTNESSDOWN = 275;
+    SDL_SCANCODE_BRIGHTNESSUP = 276;
+    SDL_SCANCODE_DISPLAYSWITCH = 277;
+    SDL_SCANCODE_KBDILLUMTOGGLE = 278;
+    SDL_SCANCODE_KBDILLUMDOWN = 279;
+    SDL_SCANCODE_KBDILLUMUP = 280;
+    SDL_SCANCODE_EJECT = 281;
+    SDL_SCANCODE_SLEEP = 282;
+    SDL_SCANCODE_APP1 = 283;
+    SDL_SCANCODE_APP2 = 284;
 
 /////////////////////////////////////////////////////////////////
 ///////////////////////  TYPE DEFINITIONS ///////////////////////
@@ -319,25 +530,20 @@
 // http://www.freepascal.org/docs-html/prog/progsu144.html
 
 type
-{$IFDEF SDL2}
     PSDL_Window   = Pointer;
     PSDL_Renderer = Pointer;
     PSDL_Texture  = Pointer;
     PSDL_GLContext= Pointer;
     TSDL_TouchId  = Int64;
-{$ENDIF}
     TSDL_FingerId = Int64;
+    TSDL_Keycode = LongInt;
+    TSDL_Scancode = LongInt;
 
     TSDL_eventaction = (SDL_ADDEVENT, SDL_PEEPEVENT, SDL_GETEVENT);
 
     PSDL_Rect = ^TSDL_Rect;
     TSDL_Rect = record
-{$IFDEF SDL2}
         x, y, w, h: LongInt;
-{$ELSE}
-        x, y: SmallInt;
-        w, h: Word;
-{$ENDIF}
         end;
 
     TPoint = record
@@ -346,7 +552,6 @@
 
     PSDL_PixelFormat = ^TSDL_PixelFormat;
     TSDL_PixelFormat = record
-{$IFDEF SDL2}
         format: LongWord;
         palette: Pointer;
         BitsPerPixel : Byte;
@@ -366,25 +571,6 @@
         Ashift: Byte;
         refcount: LongInt;
         next: PSDL_PixelFormat;
-{$ELSE}
-        palette: Pointer;
-        BitsPerPixel : Byte;
-        BytesPerPixel: Byte;
-        Rloss : Byte;
-        Gloss : Byte;
-        Bloss : Byte;
-        Aloss : Byte;
-        Rshift: Byte;
-        Gshift: Byte;
-        Bshift: Byte;
-        Ashift: Byte;
-        RMask : LongWord;
-        GMask : LongWord;
-        BMask : LongWord;
-        AMask : LongWord;
-        colorkey: LongWord;
-        alpha: Byte;
-{$ENDIF}
         end;
 
     PSDL_Surface = ^TSDL_Surface;
@@ -392,7 +578,7 @@
         flags : LongWord;
         format: PSDL_PixelFormat;
         w, h  : LongInt;
-        pitch : {$IFDEF SDL2}LongInt{$ELSE}Word{$ENDIF};
+        pitch : LongInt;
         pixels: Pointer;
 {$IFDEF PAS2C}
         hwdata   : Pointer;
@@ -404,16 +590,12 @@
         refcount : LongInt;
         offset   : LongInt;
 {$ELSE}
-{$IFDEF SDL2}
         userdata  : Pointer;
         locked    : LongInt;
         lock_data : Pointer;
         clip_rect : TSDL_Rect;
         map       : Pointer;
         refcount  : LongInt;
-{$ELSE}
-        offset : LongInt;
-{$ENDIF}
 {$ENDIF}
         end;
 
@@ -429,18 +611,14 @@
 
     (* SDL_RWops and friends *)
     PSDL_RWops = ^TSDL_RWops;
-{$IFDEF SDL2}
     TSize  = function( context: PSDL_RWops): Int64; cdecl;
     TSeek  = function( context: PSDL_RWops; offset: Int64; whence: LongInt ): Int64; cdecl;
-{$ELSE}
-    TSeek  = function( context: PSDL_RWops; offset: LongInt; whence: LongInt ): LongInt; cdecl;
-{$ENDIF}
     TRead  = function( context: PSDL_RWops; Ptr: Pointer; size: LongInt; maxnum : LongInt ): LongInt;  cdecl;
     TWrite = function( context: PSDL_RWops; Ptr: Pointer; size: LongInt; num: LongInt ): LongInt; cdecl;
     TClose = function( context: PSDL_RWops ): LongInt; cdecl;
 
     TStdio = record
-        autoclose: {$IFDEF SDL2}Boolean{$ELSE}LongInt{$ENDIF};
+        autoclose: Boolean;
         fp: Pointer;
         end;
 
@@ -452,9 +630,7 @@
 
     TUnknown = record
         data1: Pointer;
-{$IFDEF SDL2}
         data2: Pointer;
-{$ENDIF}
         end;
 
 {$IFDEF ANDROID}
@@ -471,7 +647,7 @@
         size, left: LongInt;
         end;
     TWindowsio = record
-        append : {$IFDEF SDL2}Boolean{$ELSE}LongInt{$ENDIF};
+        append : Boolean;
         h : Pointer;
         buffer : TWinbuffer;
         end;
@@ -479,9 +655,7 @@
 {$ENDIF}
 
     TSDL_RWops = record
-{$IFDEF SDL2}
         size: TSize;
-{$ENDIF}
         seek: TSeek;
         read: TRead;
         write: TWrite;
@@ -503,10 +677,9 @@
 
 {* SDL_Event type definition *}
 
-{$IFDEF SDL2}
     TSDL_Keysym = record
-        scancode: LongInt;
-        sym: LongInt;
+        scancode: TSDL_Scancode;
+        sym: TSDL_Keycode;
         modifier: Word;
         unused: LongWord;
         end;
@@ -520,21 +693,20 @@
         data1, data2: LongInt;
         end;
 
-    // available in sdl12 but not exposed
     TSDL_TextEditingEvent = record
-        type_: LongWord;
-        timestamp: LongWord;
-        windowID: LongWord;
-        text: array[0..31] of Byte;
-        start, lenght: LongInt;
+        type_: Longword;
+        timestamp: Longword;
+        windowID: Longword;
+        text: array [0..SDL_TEXTEDITINGEVENT_TEXT_SIZE - 1] of char;
+        start: LongInt;
+        length: LongInt;
         end;
 
-    // available in sdl12 but not exposed
     TSDL_TextInputEvent = record
-        type_: LongWord;
-        timestamp: LongWord;
-        windowID: LongWord;
-        text: array[0..31] of Byte;
+        type_: Longword;
+        timestamp: Longword;
+        windowID: Longword;
+        text: array [0..SDL_TEXTINPUTEVENT_TEXT_SIZE - 1] of char;
         end;
 
     TSDL_TouchFingerEvent = record
@@ -605,167 +777,92 @@
         end;
 
     TSDL_OSEvent = TSDL_CommonEvent;
-{$ELSE}
-    TSDL_KeySym = record
-        scancode: Byte;
-        sym: LongWord;
-        modifier: LongWord;
-        unicode: Word;
-        end;
-
-    TSDL_ActiveEvent = record
-        type_: Byte;
-        gain: Byte;
-        state: Byte;
-        end;
-
-    TSDL_ResizeEvent = record
-        type_: Byte;
-        w, h: LongInt;
-        end;
-{$ENDIF}
 
     TSDL_KeyboardEvent = record
-{$IFDEF SDL2}
         type_: LongWord;
         timestamp: LongWord;
         windowID: LongWord;
         state, repeat_, padding2, padding3: Byte;
-{$ELSE}
-        type_, which, state: Byte;
-{$ENDIF}
         keysym: TSDL_Keysym;
         end;
 
     TSDL_MouseMotionEvent = record
-{$IFDEF SDL2}
         type_: LongWord;
         timestamp: LongWord;
         windowID: LongWord;
         which, state: LongWord;
         x, y, xrel, yrel: LongInt;
-{$ELSE}
-        type_, which, state: Byte;
-        x, y, xrel, yrel: Word;
-{$ENDIF}
         end;
 
     TSDL_MouseButtonEvent = record
-{$IFDEF SDL2}
         type_: LongWord;
         timestamp: LongWord;
         windowID: LongWord;
         which: LongWord;
         button, state, padding1, padding2: Byte;
         x, y: LongInt;
-{$ELSE}
-        type_, which, button, state: Byte;
-        x, y: Word;
-{$ENDIF}
         end;
 
     TSDL_MouseWheelEvent = record
         type_: LongWord;
-{$IFDEF SDL2}
         timestamp: LongWord;
         windowID: LongWord;
         which: LongWord;
-{$ELSE}
-        which: Byte;
-{$ENDIF}
         x, y: LongInt;
         end;
 
     TSDL_JoyAxisEvent = record
-{$IFDEF SDL2}
         type_: LongWord;
         timestamp: LongWord;
         which: LongWord;
-{$ELSE}
-        type_: Byte;
-        which: Byte;
-{$ENDIF}
         axis: Byte;
-{$IFDEF SDL2}
         padding1, padding2, padding3: Byte;
         value: LongInt;
         padding4: Word;
-{$ELSE}
-        value: SmallInt;
-{$ENDIF}
         end;
 
     TSDL_JoyBallEvent = record
-{$IFDEF SDL2}
         type_: LongWord;
         timestamp: LongWord;
         which: LongWord;
-{$ELSE}
-        type_: Byte;
-        which: Byte;
-{$ENDIF}
         ball: Byte;
-{$IFDEF SDL2}
         padding1, padding2, padding3: Byte;
-{$ENDIF}
         xrel, yrel: SmallInt;
         end;
 
     TSDL_JoyHatEvent = record
-{$IFDEF SDL2}
         type_: LongWord;
         timestamp: LongWord;
         which: LongWord;
-{$ELSE}
-        type_: Byte;
-        which: Byte;
-{$ENDIF}
         hat: Byte;
         value: Byte;
-{$IFDEF SDL2}
         padding1, padding2: Byte;
-{$ENDIF}
         end;
 
     TSDL_JoyButtonEvent = record
-{$IFDEF SDL2}
         type_: LongWord;
         timestamp: LongWord;
-{$ELSE}
-        type_: Byte;
-{$ENDIF}
         which: Byte;
         button: Byte;
         state: Byte;
-{$IFDEF SDL2}
         padding1: Byte;
-{$ENDIF}
         end;
 
     TSDL_QuitEvent = record
-{$IFDEF SDL2}
         type_: LongWord;
         timestamp: LongWord;
-{$ELSE}
-        type_: Byte;
-{$ENDIF}
         end;
 
     TSDL_UserEvent = record
-{$IFDEF SDL2}
         type_: LongWord;
         timestamp: LongWord;
         windowID: LongWord;
-{$ELSE}
-        type_: Byte;
-{$ENDIF}
         code: LongInt;
         data1, data2: Pointer;
         end;
 
     PSDL_Event = ^TSDL_Event;
     TSDL_Event = record
-{$IFDEF SDL2}
         case LongInt of
             SDL_FIRSTEVENT: (type_: LongWord);
             SDL_COMMONDEVENT: (common: TSDL_CommonEvent);
@@ -773,7 +870,7 @@
             SDL_KEYDOWN,
             SDL_KEYUP: (key: TSDL_KeyboardEvent);
             SDL_TEXTEDITING: (edit: TSDL_TextEditingEvent);
-            SDL_TEXTINPUT: (tedit: TSDL_TextInputEvent);
+            SDL_TEXTINPUT: (text: TSDL_TextInputEvent);
             SDL_MOUSEMOTION: (motion: TSDL_MouseMotionEvent);
             SDL_MOUSEBUTTONDOWN,
             SDL_MOUSEBUTTONUP: (button: TSDL_MouseButtonEvent);
@@ -801,25 +898,6 @@
             SDL_DOLLARGESTURE: (dgesture: TSDL_DollarGestureEvent);
             SDL_DROPFILE: (drop: TSDL_DropEvent);
             SDL_ALLEVENTS: (foo: shortstring);
-{$ELSE}
-        case Byte of
-            SDL_NOEVENT: (type_: Byte);
-            SDL_ACTIVEEVENT: (active: TSDL_ActiveEvent);
-            SDL_KEYDOWN,
-            SDL_KEYUP: (key: TSDL_KeyboardEvent);
-            SDL_MOUSEMOTION: (motion: TSDL_MouseMotionEvent);
-            SDL_MOUSEBUTTONDOWN,
-            SDL_MOUSEBUTTONUP: (button: TSDL_MouseButtonEvent);
-            SDL_JOYAXISMOTION: (jaxis: TSDL_JoyAxisEvent);
-            SDL_JOYHATMOTION: (jhat: TSDL_JoyHatEvent);
-            SDL_JOYBALLMOTION: (jball: TSDL_JoyBallEvent);
-            SDL_JOYBUTTONDOWN,
-            SDL_JOYBUTTONUP: (jbutton: TSDL_JoyButtonEvent);
-            SDL_QUITEV: (quit: TSDL_QuitEvent);
-            //SDL_SYSWMEVENT,SDL_EVENT_RESERVEDA,SDL_EVENT_RESERVEDB
-            SDL_VIDEORESIZE: (resize: TSDL_ResizeEvent);
-            SDL_ALLEVENTS: (foo: shortstring);
-{$ENDIF}
         end;
 
     TSDL_EventFilter = function( event : PSDL_Event ): Integer; cdecl;
@@ -852,7 +930,6 @@
         SDL_GL_MULTISAMPLEBUFFERS,
         SDL_GL_MULTISAMPLESAMPLES,
         SDL_GL_ACCELERATED_VISUAL,
-{$IFDEF SDL2}
         SDL_GL_RETAINED_BACKING,
         SDL_GL_CONTEXT_MAJOR_VERSION,
         SDL_GL_CONTEXT_MINOR_VERSION,
@@ -860,12 +937,8 @@
         SDL_GL_CONTEXT_FLAGS,
         SDL_GL_CONTEXT_PROFILE_MASK,
         SDL_GL_SHARE_WITH_CURRENT_CONTEXT
-{$ELSE}
-        SDL_GL_SWAP_CONTROL
-{$ENDIF}
         );
 
-{$IFDEF SDL2}
     TSDL_ArrayByteOrder = (  // array component order, low Byte -> high Byte
         SDL_ARRAYORDER_NONE,
         SDL_ARRAYORDER_RGB,
@@ -875,7 +948,6 @@
         SDL_ARRAYORDER_BGRA,
         SDL_ARRAYORDER_ABGR
         );
-{$ENDIF}
 
     // Joystick/Controller support
     PSDL_Joystick = ^TSDL_Joystick;
@@ -947,6 +1019,8 @@
 function  SDL_InitSubSystem(flags: LongWord): LongInt; cdecl; external SDLLibName;
 procedure SDL_Quit; cdecl; external SDLLibName;
 
+procedure SDL_free(mem: Pointer); cdecl; external SDLLibName;
+
 procedure SDL_Delay(msec: LongWord); cdecl; external SDLLibName;
 function  SDL_GetTicks: LongWord; cdecl; external SDLLibName;
 
@@ -980,8 +1054,9 @@
 function  SDL_RWFromFile(filename, mode: PChar): PSDL_RWops; cdecl; external SDLLibName;
 function  SDL_SaveBMP_RW(surface: PSDL_Surface; dst: PSDL_RWops; freedst: LongInt): LongInt; cdecl; external SDLLibName;
 
-{$IFDEF SDL2}
 function  SDL_CreateWindow(title: PChar; x,y,w,h: LongInt; flags: LongWord): PSDL_Window; cdecl; external SDLLibName;
+procedure SDL_SetWindowIcon(window: PSDL_Window; icon: PSDL_Surface); cdecl; external SDLLibName;
+
 function  SDL_CreateRenderer(window: PSDL_Window; index: LongInt; flags: LongWord): PSDL_Renderer; cdecl; external SDLLibName;
 function  SDL_DestroyWindow(window: PSDL_Window): LongInt; cdecl; external SDLLibName;
 function  SDL_DestroyRenderer(renderer: PSDL_Renderer): LongInt; cdecl; external SDLLibName;
@@ -990,7 +1065,7 @@
 
 function  SDL_GL_CreateContext(window: PSDL_Window): PSDL_GLContext; cdecl; external SDLLibName;
 procedure SDL_GL_DeleteContext(context: PSDL_GLContext); cdecl; external SDLLibName;
-function  SDL_GL_SwapWindow(window: PSDL_Window): LongInt; cdecl; external SDLLibName;
+procedure SDL_GL_SwapWindow(window: PSDL_Window); cdecl; external SDLLibName;
 function  SDL_GL_SetSwapInterval(interval: LongInt): LongInt; cdecl; external SDLLibName;
 
 procedure SDL_VideoQuit; cdecl; external SDLLibName;
@@ -1011,25 +1086,19 @@
 procedure SDL_WarpMouseInWindow(window: PSDL_Window; x, y: LongInt); cdecl; external SDLLibName;
 function  SDL_SetHint(name, value: PChar): Boolean; cdecl; external SDLLibName;
 procedure SDL_StartTextInput; cdecl; external SDLLibName;
+procedure SDL_StopTextInput; cdecl; external SDLLibName;
 
 function  SDL_PeepEvents(event: PSDL_Event; numevents: LongInt; action: TSDL_eventaction; minType, maxType: LongWord): LongInt; cdecl; external SDLLibName;
 
 function  SDL_AllocFormat(format: LongWord): PSDL_PixelFormat; cdecl; external SDLLibName;
 procedure SDL_FreeFormat(pixelformat: PSDL_PixelFormat); cdecl; external SDLLibName;
-{$ELSE}
-function  SDL_PeepEvents(event: PSDL_Event; numevents: LongInt; action: TSDL_eventaction; mask: LongWord): LongInt; cdecl; external SDLLibName;
-
-function  SDL_EnableUNICODE(enable: LongInt): LongInt; cdecl; external SDLLibName;
-function  SDL_EnableKeyRepeat(timedelay, interval: LongInt): LongInt; cdecl; external SDLLibName;
-function  SDL_VideoDriverName(namebuf: PChar; maxlen: LongInt): PChar; cdecl; external SDLLibName;
-{$ENDIF}
 
 
 function  SDL_GetMouseState(x, y: PLongInt): Byte; cdecl; external SDLLibName;
-function  SDL_GetKeyName(key: LongWord): PChar; cdecl; external SDLLibName;
-function  SDL_GetScancodeName(key: LongWord): PChar; cdecl; external SDLLibName;
-function  SDL_GetKeyFromScancode(key: LongWord): LongInt; cdecl; external SDLLibName;
-
+function  SDL_GetKeyName(key: TSDL_Keycode): PChar; cdecl; external SDLLibName;
+function  SDL_GetScancodeName(key: TSDL_Scancode): PChar; cdecl; external SDLLibName;
+function  SDL_GetKeyFromScancode(key: TSDL_Scancode): TSDL_Keycode; cdecl; external SDLLibName;
+// SDL2 functions has some additional functions (not listed here) for keycode/scancode translation
 
 procedure SDL_PumpEvents; cdecl; external SDLLibName;
 function  SDL_PollEvent(event: PSDL_Event): LongInt; cdecl; external SDLLibName;
@@ -1037,8 +1106,9 @@
 procedure SDL_SetEventFilter(filter: TSDL_EventFilter); cdecl; external SDLLibName;
 
 function  SDL_ShowCursor(toggle: LongInt): LongInt; cdecl; external SDLLibName;
-procedure SDL_WarpMouse(x, y: Word); {$IFDEF SDL2}inline{$ELSE}cdecl; external SDLLibName{$ENDIF};
-function  SDL_GetKeyState(numkeys: PLongInt): PByteArray; cdecl; external SDLLibName {$IFDEF SDL2} name 'SDL_GetKeyboardState'{$ENDIF};
+procedure SDL_WarpMouse(x, y: Word); inline;
+
+function  SDL_GetKeyboardState(numkeys: PLongInt): PByteArray; cdecl; external SDLLibName;
 
 procedure SDL_WM_SetIcon(icon: PSDL_Surface; mask : Byte); cdecl; external SDLLibName;
 procedure SDL_WM_SetCaption(title: PChar; icon: PChar); cdecl; external SDLLibName;
@@ -1047,14 +1117,13 @@
 
 (* remember to mark the threaded functions as 'cdecl; export;'
    (or have fun debugging nil arguments) *)
-function  SDL_CreateThread(fn: Pointer; {$IFDEF SDL2}name: PChar;{$ENDIF} data: Pointer): PSDL_Thread; cdecl; external SDLLibName;
+function  SDL_CreateThread(fn: Pointer; name: PChar; data: Pointer): PSDL_Thread; cdecl; external SDLLibName;
 procedure SDL_WaitThread(thread: PSDL_Thread; status: PLongInt); cdecl; external SDLLibName;
-procedure SDL_KillThread(thread: PSDL_Thread); cdecl; external SDLLibName;
 
 function  SDL_CreateMutex: PSDL_mutex; cdecl; external SDLLibName;
 procedure SDL_DestroyMutex(mutex: PSDL_mutex); cdecl; external SDLLibName;
-function  SDL_LockMutex(mutex: PSDL_mutex): LongInt; cdecl; external SDLLibName {$IFNDEF SDL2}name 'SDL_mutexP'{$ENDIF};
-function  SDL_UnlockMutex(mutex: PSDL_mutex): LongInt; cdecl; external SDLLibName {$IFNDEF SDL2}name 'SDL_mutexV'{$ENDIF};
+function  SDL_LockMutex(mutex: PSDL_mutex): LongInt; cdecl; external SDLLibName;
+function  SDL_UnlockMutex(mutex: PSDL_mutex): LongInt; cdecl; external SDLLibName;
 
 function  SDL_CreateCond: PSDL_cond; cdecl; external SDLLibName;
 procedure SDL_DestroyCond(cond: PSDL_cond); cdecl; external SDLLibName;
@@ -1117,8 +1186,8 @@
 procedure TTF_CloseFont(font: PTTF_Font); cdecl; external SDL_TTFLibName;
 
 (*  SDL_mixer  *)
-function  Mix_Init(flags: LongInt): LongInt; {$IFDEF SDL_MIXER_NEWER}cdecl; external SDL_MixerLibName{$ELSE}inline{$ENDIF};
-procedure Mix_Quit; {$IFDEF SDL_MIXER_NEWER}cdecl; external SDL_MixerLibName{$ELSE}inline{$ENDIF};
+function  Mix_Init(flags: LongInt): LongInt; cdecl; external SDL_MixerLibName;
+procedure Mix_Quit; cdecl; external SDL_MixerLibName;
 
 function  Mix_OpenAudio(frequency: LongInt; format: Word; channels: LongInt; chunksize: LongInt): LongInt; cdecl; external SDL_MixerLibName;
 procedure Mix_CloseAudio; cdecl; external SDL_MixerLibName;
@@ -1153,8 +1222,8 @@
 procedure Mix_SetPostMix( mix_func: TPostMix; arg: Pointer); cdecl; external SDL_MixerLibName;
 
 (*  SDL_image  *)
-function  IMG_Init(flags: LongInt): LongInt; {$IFDEF SDL_IMAGE_NEWER}cdecl; external SDL_ImageLibName{$ELSE}inline{$ENDIF};
-procedure IMG_Quit; {$IFDEF SDL_IMAGE_NEWER}cdecl; external SDL_ImageLibName{$ELSE}inline{$ENDIF};
+function  IMG_Init(flags: LongInt): LongInt; cdecl; external SDL_ImageLibName;
+procedure IMG_Quit; cdecl; external SDL_ImageLibName;
 
 function  IMG_Load(const _file: PChar): PSDL_Surface; cdecl; external SDL_ImageLibName;
 function  IMG_Load_RW(rwop: PSDL_RWops; freesrc: LongBool): PSDL_Surface; cdecl; external SDL_ImageLibName;
@@ -1176,6 +1245,12 @@
 function  SDLNet_AddSocket(_set: PSDLNet_SocketSet; sock: PTCPSocket): LongInt; cdecl; external SDL_NetLibName;
 function  SDLNet_CheckSockets(_set: PSDLNet_SocketSet; timeout: LongInt): LongInt; cdecl; external SDL_NetLibName;
 
+// SDL 2 clipboard functions
+function SDL_HasClipboardText(): Boolean; cdecl; external SDLLibName;
+// returns nil if memory for clipboard contents copy couldn't be allocated
+function SDL_GetClipboardText(): PChar; cdecl; external SDLLibName;
+// returns 0 on success or negative error number on failure
+function SDL_SetClipboardText(const text: PChar): LongInt; cdecl; external SDLLibName;
 
 procedure SDLNet_Write16(value: Word; buf: Pointer);
 procedure SDLNet_Write32(value: LongWord; buf: Pointer);
@@ -1183,7 +1258,6 @@
 function  SDLNet_Read32(buf: Pointer): LongWord;
 
 implementation
-{$IFDEF SDL2}
 uses uStore;
 
 // for sdl1.2 we directly call SDL_WarpMouse()
@@ -1194,40 +1268,13 @@
 begin
     WarpMouse(x, y);
 end;
-{$ENDIF}
 
 function SDL_MustLock(Surface: PSDL_Surface): Boolean;
 begin
     SDL_MustLock:=
-{$IFDEF SDL2}
         ((surface^.flags and SDL_RLEACCEL) <> 0)
-{$ELSE}
-        ( surface^.offset <> 0 ) or (( surface^.flags and (SDL_HWSURFACE or SDL_ASYNCBLIT or SDL_RLEACCEL)) <> 0)
-{$ENDIF}
-end;
-
-{$IFNDEF SDL_MIXER_NEWER}
-function  Mix_Init(flags: LongInt): LongInt; inline;
-begin
-    Mix_Init:= flags;
 end;
 
-procedure Mix_Quit; inline;
-begin
-end;
-{$ENDIF}
-
-{$IFNDEF SDL_IMAGE_NEWER}
-function  IMG_Init(flags: LongInt): LongInt; inline;
-begin
-    IMG_Init:= flags;
-end;
-
-procedure IMG_Quit; inline;
-begin
-end;
-{$ENDIF}
-
 procedure SDLNet_Write16(value: Word; buf: Pointer);
 begin
     PByteArray(buf)^[1]:= value;
@@ -1256,5 +1303,6 @@
                   (PByteArray(buf)^[0] shl 24)
 end;
 
+
 end.
 
--- a/hedgewars/avwrapper/CMakeLists.txt	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/avwrapper/CMakeLists.txt	Mon Nov 16 22:57:24 2015 +0300
@@ -1,9 +1,5 @@
 #libraries have already been searched in main CMakeLists.txt
 
-# TODO: this check is only for SDL < 2
-# fpc will take care of linking but we need to have this library installed
-find_package(GLUT REQUIRED)
-
 include_directories(${LIBAV_INCLUDE_DIR})
 
 add_library(avwrapper avwrapper.c)
--- a/hedgewars/avwrapper/avwrapper.c	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/avwrapper/avwrapper.c	Mon Nov 16 22:57:24 2015 +0300
@@ -21,13 +21,12 @@
 #include <stdint.h>
 #include <string.h>
 #include <stdarg.h>
+
+#include "libavcodec/avcodec.h"
 #include "libavformat/avformat.h"
+#include "libavutil/avutil.h"
 #include "libavutil/mathematics.h"
 
-#ifndef AVIO_FLAG_WRITE
-#define AVIO_FLAG_WRITE AVIO_WRONLY
-#endif
-
 #if (defined _MSC_VER)
 #define AVWRAP_DECL __declspec(dllexport)
 #elif ((__GNUC__ >= 3) && (!__EMX__) && (!sun))
@@ -57,11 +56,55 @@
 static int g_NumSamples;
 
 
+// compatibility section
 #if LIBAVCODEC_VERSION_MAJOR < 54
 #define OUTBUFFER_SIZE 200000
 static uint8_t g_OutBuffer[OUTBUFFER_SIZE];
+#define avcodec_open2(x, y, z)              avcodec_open(x, y)
 #endif
 
+#if LIBAVCODEC_VERSION_MAJOR < 56
+#define av_frame_alloc                      avcodec_alloc_frame
+#define av_frame_free                       av_freep
+#define av_packet_rescale_ts                rescale_ts
+
+static void rescale_ts(AVPacket *pkt, AVRational ctb, AVRational stb)
+{
+    if (pkt->pts != AV_NOPTS_VALUE)
+        pkt->pts = av_rescale_q(pkt->pts, ctb, stb);
+    if (pkt->dts != AV_NOPTS_VALUE)
+        pkt->dts = av_rescale_q(pkt->dts, ctb, stb);
+    if (pkt->duration > 0)
+        pkt->duration = av_rescale_q(pkt->duration, ctb, stb);
+}
+#endif
+
+#ifndef AV_CODEC_CAP_DELAY
+#define AV_CODEC_CAP_DELAY                  CODEC_CAP_DELAY
+#endif
+#ifndef AV_CODEC_CAP_VARIABLE_FRAME_SIZE
+#define AV_CODEC_CAP_VARIABLE_FRAME_SIZE    CODEC_CAP_VARIABLE_FRAME_SIZE
+#endif
+#ifndef AV_CODEC_FLAG_GLOBAL_HEADER
+#define AV_CODEC_FLAG_GLOBAL_HEADER         CODEC_FLAG_GLOBAL_HEADER
+#endif
+#ifndef AV_CODEC_FLAG_QSCALE
+#define AV_CODEC_FLAG_QSCALE                CODEC_FLAG_QSCALE
+#endif
+
+#if LIBAVFORMAT_VERSION_MAJOR < 53
+#define AVIO_FLAG_WRITE                     AVIO_WRONLY
+#endif
+
+#if LIBAVFORMAT_VERSION_MAJOR < 54
+#define avformat_new_stream(x, y)           av_new_stream(x, y->type == AVMEDIA_TYPE_AUDIO)
+#endif
+
+#if LIBAVUTIL_VERSION_MAJOR < 54
+#define AV_PIX_FMT_YUV420P                  PIX_FMT_YUV420P
+#endif
+
+
 // pointer to function from hwengine (uUtils.pas)
 static void (*AddFileLogRaw)(const char* pString);
 
@@ -105,11 +148,7 @@
 
 static void AddAudioStream()
 {
-#if LIBAVFORMAT_VERSION_MAJOR >= 53
     g_pAStream = avformat_new_stream(g_pContainer, g_pACodec);
-#else
-    g_pAStream = av_new_stream(g_pContainer, 1);
-#endif
     if(!g_pAStream)
     {
         Log("Could not allocate audio stream\n");
@@ -127,30 +166,30 @@
     g_pAudio->sample_rate = g_Frequency;
     g_pAudio->channels = g_Channels;
 
+    // set time base as invers of sample rate
+    g_pAudio->time_base.den = g_pAStream->time_base.den = g_Frequency;
+    g_pAudio->time_base.num = g_pAStream->time_base.num = 1;
+
     // set quality
     g_pAudio->bit_rate = 160000;
 
     // for codecs that support variable bitrate use it, it should be better
-    g_pAudio->flags |= CODEC_FLAG_QSCALE;
+    g_pAudio->flags |= AV_CODEC_FLAG_QSCALE;
     g_pAudio->global_quality = 1*FF_QP2LAMBDA;
 
     // some formats want stream headers to be separate
     if (g_pFormat->flags & AVFMT_GLOBALHEADER)
-        g_pAudio->flags |= CODEC_FLAG_GLOBAL_HEADER;
+        g_pAudio->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
 
     // open it
-#if LIBAVCODEC_VERSION_MAJOR >= 53
     if (avcodec_open2(g_pAudio, g_pACodec, NULL) < 0)
-#else
-    if (avcodec_open(g_pAudio, g_pACodec) < 0)
-#endif
     {
         Log("Could not open audio codec %s\n", g_pACodec->long_name);
         return;
     }
 
 #if LIBAVCODEC_VERSION_MAJOR >= 54
-    if (g_pACodec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)
+    if (g_pACodec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
 #else
     if (g_pAudio->frame_size == 0)
 #endif
@@ -158,7 +197,7 @@
     else
         g_NumSamples = g_pAudio->frame_size;
     g_pSamples = (int16_t*)av_malloc(g_NumSamples*g_Channels*sizeof(int16_t));
-    g_pAFrame = avcodec_alloc_frame();
+    g_pAFrame = av_frame_alloc();
     if (!g_pAFrame)
     {
         Log("Could not allocate frame\n");
@@ -172,8 +211,10 @@
     if (!g_pAStream)
         return 0;
 
-    AVPacket Packet = { 0 };
+    AVPacket Packet;
     av_init_packet(&Packet);
+    Packet.data = NULL;
+    Packet.size = 0;
 
     int NumSamples = fread(g_pSamples, 2*g_Channels, g_NumSamples, g_pSoundFile);
 
@@ -192,6 +233,8 @@
         return FatalError("avcodec_encode_audio2 failed");
     if (!got_packet)
         return 0;
+
+    av_packet_rescale_ts(&Packet, g_pAudio->time_base, g_pAStream->time_base);
 #else
     if (NumSamples == 0)
         return 0;
@@ -217,11 +260,7 @@
 // add a video output stream
 static int AddVideoStream()
 {
-#if LIBAVFORMAT_VERSION_MAJOR >= 53
     g_pVStream = avformat_new_stream(g_pContainer, g_pVCodec);
-#else
-    g_pVStream = av_new_stream(g_pContainer, 0);
-#endif
     if (!g_pVStream)
         return FatalError("Could not allocate video stream");
 
@@ -238,23 +277,23 @@
        of which frame timestamps are represented. for fixed-fps content,
        timebase should be 1/framerate and timestamp increments should be
        identically 1. */
-    g_pVideo->time_base.den = g_Framerate.num;
-    g_pVideo->time_base.num = g_Framerate.den;
-    //g_pVideo->gop_size = 12; /* emit one intra frame every twelve frames at most */
-    g_pVideo->pix_fmt = PIX_FMT_YUV420P;
+    g_pVideo->time_base.den = g_pVStream->time_base.den = g_Framerate.num;
+    g_pVideo->time_base.num = g_pVStream->time_base.num = g_Framerate.den;
+
+    g_pVideo->pix_fmt = AV_PIX_FMT_YUV420P;
 
     // set quality
     if (g_VQuality > 100)
         g_pVideo->bit_rate = g_VQuality;
     else
     {
-        g_pVideo->flags |= CODEC_FLAG_QSCALE;
+        g_pVideo->flags |= AV_CODEC_FLAG_QSCALE;
         g_pVideo->global_quality = g_VQuality*FF_QP2LAMBDA;
     }
 
     // some formats want stream headers to be separate
     if (g_pFormat->flags & AVFMT_GLOBALHEADER)
-        g_pVideo->flags |= CODEC_FLAG_GLOBAL_HEADER;
+        g_pVideo->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
 
 #if LIBAVCODEC_VERSION_MAJOR < 53
     // for some versions of ffmpeg x264 options must be set explicitly
@@ -288,21 +327,16 @@
 #endif
 
     // open the codec
-#if LIBAVCODEC_VERSION_MAJOR >= 53
-    AVDictionary* pDict = NULL;
-    if (strcmp(g_pVCodec->name, "libx264") == 0)
-        av_dict_set(&pDict, "preset", "medium", 0);
-
-    if (avcodec_open2(g_pVideo, g_pVCodec, &pDict) < 0)
-#else
-    if (avcodec_open(g_pVideo, g_pVCodec) < 0)
-#endif
+    if (avcodec_open2(g_pVideo, g_pVCodec, NULL) < 0)
         return FatalError("Could not open video codec %s", g_pVCodec->long_name);
 
-    g_pVFrame = avcodec_alloc_frame();
+    g_pVFrame = av_frame_alloc();
     if (!g_pVFrame)
         return FatalError("Could not allocate frame");
 
+    g_pVFrame->width = g_Width;
+    g_pVFrame->height = g_Height;
+    g_pVFrame->format = AV_PIX_FMT_YUV420P;
     g_pVFrame->linesize[0] = g_Width;
     g_pVFrame->linesize[1] = g_Width/2;
     g_pVFrame->linesize[2] = g_Width/2;
@@ -317,10 +351,10 @@
     // write interleaved audio frame
     if (g_pAStream)
     {
-        VideoTime = (double)g_pVStream->pts.val*g_pVStream->time_base.num/g_pVStream->time_base.den;
+        VideoTime = (double)g_pVFrame->pts * g_pVStream->time_base.num/g_pVStream->time_base.den;
         do
         {
-            AudioTime = (double)g_pAStream->pts.val*g_pAStream->time_base.num/g_pAStream->time_base.den;
+            AudioTime = (double)g_pAFrame->pts * g_pAStream->time_base.num/g_pAStream->time_base.den;
             ret = WriteAudioFrame();
         }
         while (AudioTime < VideoTime && ret);
@@ -337,6 +371,7 @@
     Packet.size = 0;
 
     g_pVFrame->pts++;
+#if LIBAVCODEC_VERSION_MAJOR < 58
     if (g_pFormat->flags & AVFMT_RAWPICTURE)
     {
         /* raw video case. The API will change slightly in the near
@@ -351,6 +386,7 @@
         return 0;
     }
     else
+#endif
     {
 #if LIBAVCODEC_VERSION_MAJOR >= 54
         int got_packet;
@@ -359,10 +395,7 @@
         if (!got_packet)
             return 0;
 
-        if (Packet.pts != AV_NOPTS_VALUE)
-            Packet.pts = av_rescale_q(Packet.pts, g_pVideo->time_base, g_pVStream->time_base);
-        if (Packet.dts != AV_NOPTS_VALUE)
-            Packet.dts = av_rescale_q(Packet.dts, g_pVideo->time_base, g_pVStream->time_base);
+        av_packet_rescale_ts(&Packet, g_pVideo->time_base, g_pVStream->time_base);
 #else
         Packet.size = avcodec_encode_video(g_pVideo, g_OutBuffer, OUTBUFFER_SIZE, pFrame);
         if (Packet.size < 0)
@@ -496,11 +529,11 @@
 {
     int ret;
     // output buffered frames
-    if (g_pVCodec->capabilities & CODEC_CAP_DELAY)
+    if (g_pVCodec->capabilities & AV_CODEC_CAP_DELAY)
     {
         do
             ret = WriteFrame(NULL);
-        while (ret >= 0);
+        while (ret > 0);
         if (ret < 0)
             return ret;
     }
@@ -509,7 +542,7 @@
     {
         ret = WriteAudioFrame();
     }
-    while(ret >= 0);
+    while(ret > 0);
     if (ret < 0)
         return ret;
 
@@ -526,14 +559,14 @@
         avcodec_close(g_pVideo);
         av_free(g_pVideo);
         av_free(g_pVStream);
-        av_free(g_pVFrame);
+        av_frame_free(&g_pVFrame);
     }
     if (g_pAStream)
     {
         avcodec_close(g_pAudio);
         av_free(g_pAudio);
         av_free(g_pAStream);
-        av_free(g_pAFrame);
+        av_frame_free(&g_pAFrame);
         av_free(g_pSamples);
         fclose(g_pSoundFile);
     }
--- a/hedgewars/hwengine.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/hwengine.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -25,7 +25,7 @@
 unit hwengine;
 interface
 
-uses SDLh, uMisc, uConsole, uGame, uConsts, uLand, uAmmos, uVisualGears, uGears, uStore, uWorld, uInputHandler
+uses {$IFDEF IPHONEOS}cmem, {$ENDIF} SDLh, uMisc, uConsole, uGame, uConsts, uLand, uAmmos, uVisualGears, uGears, uStore, uWorld, uInputHandler
      , uSound, uScript, uTeams, uStats, uIO, uLocale, uChat, uAI, uAIMisc, uAILandMarks, uLandTexture, uCollisions
      , SysUtils, uTypes, uVariables, uCommands, uUtils, uCaptions, uDebug, uCommandHandlers, uLandPainted
      , uPhysFSLayer, uCursor, uRandom, ArgParsers, uVisualGearsHandlers, uTextures, uRender
@@ -143,11 +143,7 @@
 var event: TSDL_Event;
     PrevTime, CurrTime: LongWord;
     isTerminated: boolean;
-{$IFDEF SDL2}
     previousGameState: TGameState;
-{$ELSE}
-    prevFocusState: boolean;
-{$ENDIF}
 begin
     isTerminated:= false;
     PrevTime:= SDL_GetTicks;
@@ -155,15 +151,14 @@
     begin
         SDL_PumpEvents();
 
-        while SDL_PeepEvents(@event, 1, SDL_GETEVENT, {$IFDEF SDL2}SDL_FIRSTEVENT, SDL_LASTEVENT{$ELSE}SDL_ALLEVENTS{$ENDIF}) > 0 do
+        while SDL_PeepEvents(@event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT) > 0 do
         begin
             case event.type_ of
-{$IFDEF SDL2}
                 SDL_KEYDOWN:
                     if GameState = gsChat then
                         begin
                     // sdl on iphone supports only ashii keyboards and the unicode field is deprecated in sdl 1.3
-                        KeyPressChat(SDL_GetKeyFromScancode(event.key.keysym.sym), event.key.keysym.sym, event.key.keysym.modifier);
+                        KeyPressChat(event.key.keysym);
                         end
                     else
                         if GameState >= gsGame then ProcessKey(event.key);
@@ -171,6 +166,20 @@
                     if (GameState <> gsChat) and (GameState >= gsGame) then
                         ProcessKey(event.key);
 
+                SDL_MOUSEBUTTONDOWN:
+                    if GameState = gsConfirm then
+                        ParseCommand('quit', true)
+                    else
+                        if (GameState >= gsGame) then ProcessMouse(event.button, true);
+
+                SDL_MOUSEBUTTONUP:
+                    if (GameState >= gsGame) then ProcessMouse(event.button, false);
+
+                SDL_MOUSEWHEEL:
+                    ProcessMouseWheel(event.wheel.x, event.wheel.y);
+
+                SDL_TEXTINPUT: uChat.TextInput(event.text);
+
                 SDL_WINDOWEVENT:
                     if event.window.event = SDL_WINDOWEVENT_SHOWN then
                     begin
@@ -206,45 +215,6 @@
                 SDL_FINGERUP:
                     onTouchUp(event.tfinger.x, event.tfinger.y, event.tfinger.fingerId);
 {$ENDIF}
-{$ELSE}
-                SDL_KEYDOWN:
-                    if GameState = gsChat then
-                        KeyPressChat(event.key.keysym.unicode, event.key.keysym.sym, event.key.keysym.modifier)
-                    else
-                        if GameState >= gsGame then ProcessKey(event.key);
-                SDL_KEYUP:
-                    if (GameState <> gsChat) and (GameState >= gsGame) then
-                        ProcessKey(event.key);
-
-                SDL_MOUSEBUTTONDOWN:
-                    if GameState = gsConfirm then
-                        ParseCommand('quit', true)
-                    else
-                        if (GameState >= gsGame) then ProcessMouse(event.button, true);
-
-                SDL_MOUSEBUTTONUP:
-                    if (GameState >= gsGame) then ProcessMouse(event.button, false);
-
-                SDL_ACTIVEEVENT:
-                    if (event.active.state and SDL_APPINPUTFOCUS) <> 0 then
-                    begin
-                        prevFocusState:= cHasFocus;
-                        cHasFocus:= event.active.gain = 1;
-                        if prevFocusState xor cHasFocus then
-                            onFocusStateChanged()
-                    end;
-
-                SDL_VIDEORESIZE:
-                begin
-                    // using lower values than cMinScreenWidth or cMinScreenHeight causes widget overlap and off-screen widget parts
-                    // Change by sheepluva:
-                    // Let's only use even numbers for custom width/height since I ran into scaling issues with odd width values.
-                    // Maybe just fixes the symptom not the actual cause(?), I'm too tired to find out :P
-                    cNewScreenWidth:= max(2 * (event.resize.w div 2), cMinScreenWidth);
-                    cNewScreenHeight:= max(2 * (event.resize.h div 2), cMinScreenHeight);
-                    cScreenResizeDelay:= RealTicks+500;
-                end;
-{$ENDIF}
                 SDL_JOYAXISMOTION:
                     ControllerAxisEvent(event.jaxis.which, event.jaxis.axis, event.jaxis.value);
                 SDL_JOYHATMOTION:
@@ -340,20 +310,16 @@
         AddFileLog(inttostr(i) + ': ' + ParamStr(i));
 
     WriteToConsole('Init SDL... ');
-    if not cOnlyStats then SDLTry(SDL_Init(SDL_INIT_VIDEO or SDL_INIT_NOPARACHUTE) >= 0, true);
+    if not cOnlyStats then SDLTry(SDL_Init(SDL_INIT_VIDEO or SDL_INIT_NOPARACHUTE) >= 0, 'SDL_Init', true);
     WriteLnToConsole(msgOK);
 
-{$IFDEF SDL2}
-    SDL_StartTextInput();
-{$ELSE}
-    SDL_EnableUNICODE(1);
-{$ENDIF}
+    //SDL_StartTextInput();
     SDL_ShowCursor(0);
 
     if not cOnlyStats then
         begin
         WriteToConsole('Init SDL_ttf... ');
-        SDLTry(TTF_Init() <> -1, true);
+        SDLTry(TTF_Init() <> -1, 'TTF_Init', true);
         WriteLnToConsole(msgOK);
         end;
 
@@ -527,7 +493,11 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 procedure GenLandPreview;
+{$IFDEF MOBILE}
+var Preview: TPreview;
+{$ELSE}
 var Preview: TPreviewAlpha;
+{$ENDIF}
 begin
     initEverything(false);
 
@@ -535,7 +505,11 @@
     TryDo(InitStepsFlags = cifRandomize, 'Some parameters not set (flags = ' + inttostr(InitStepsFlags) + ')', true);
 
     ScriptOnPreviewInit;
+{$IFDEF MOBILE}
+    GenPreview(Preview);
+{$ELSE}
     GenPreviewAlpha(Preview);
+{$ENDIF}
     WriteLnToConsole('Sending preview...');
     SendIPCRaw(@Preview, sizeof(Preview));
     SendIPCRaw(@MaxHedgehogs, sizeof(byte));
@@ -570,7 +544,7 @@
         RunEngine:= HaltUsageError
     else
     begin
-        SDL_CreateThread(@EngineThread{$IFDEF SDL2}, 'engine'{$ENDIF}, nil);
+        SDL_CreateThread(@EngineThread, 'engine', nil);
         RunEngine:= 0
     end
 end;
--- a/hedgewars/options.inc	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/options.inc	Mon Nov 16 22:57:24 2015 +0300
@@ -60,10 +60,6 @@
     {$ENDIF}
 {$ENDIF}
 
-{$IFDEF USE_TOUCH_INTERFACE}
-    {$DEFINE SDL2}
-{$ENDIF}
-
 {$DEFINE _S:=}
 {$DEFINE _P:=}
 
--- a/hedgewars/sdlmain/CMakeLists.txt	Tue Sep 08 19:20:58 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-find_package(SDL REQUIRED)
-
-include_directories(${SDL_INCLUDE_DIR})
-
-add_library (SDLmain STATIC SDLMain.m)
-
-
--- a/hedgewars/sdlmain/SDLMain.h	Tue Sep 08 19:20:58 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-/*   SDLMain.m - main entry point for our Cocoa-ized SDL app
-       Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
-       Non-NIB-Code & other changes: Max Horn <max@quendi.de>
-
-    Feel free to customize this file to suit your needs
-*/
-
-#ifndef _SDLMain_h_
-#define _SDLMain_h_
-
-#import <Cocoa/Cocoa.h>
-
-@interface SDLMain : NSObject
-@end
-
-#endif /* _SDLMain_h_ */
--- a/hedgewars/sdlmain/SDLMain.m	Tue Sep 08 19:20:58 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,385 +0,0 @@
-/*   SDLMain.m - main entry point for our Cocoa-ized SDL app
-       Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
-       Non-NIB-Code & other changes: Max Horn <max@quendi.de>
-
-    Feel free to customize this file to suit your needs
-*/
-
-#include "SDL.h"
-#include "SDLMain.h"
-#include <sys/param.h> /* for MAXPATHLEN */
-#include <unistd.h>
-
-/* For some reaon, Apple removed setAppleMenu from the headers in 10.4,
- but the method still is there and works. To avoid warnings, we declare
- it ourselves here. */
-@interface NSApplication(SDL_Missing_Methods)
-- (void)setAppleMenu:(NSMenu *)menu;
-@end
-
-/* Use this flag to determine whether we use SDLMain.nib or not */
-#define     SDL_USE_NIB_FILE    0
-
-/* Use this flag to determine whether we use CPS (docking) or not */
-#define     SDL_USE_CPS     1
-#ifdef SDL_USE_CPS
-/* Portions of CPS.h */
-typedef struct CPSProcessSerNum
-{
-    UInt32      lo;
-    UInt32      hi;
-} CPSProcessSerNum;
-
-extern OSErr    CPSGetCurrentProcess( CPSProcessSerNum *psn);
-extern OSErr    CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
-extern OSErr    CPSSetFrontProcess( CPSProcessSerNum *psn);
-
-#endif /* SDL_USE_CPS */
-
-static int    gArgc;
-static char  **gArgv;
-static BOOL   gFinderLaunch;
-static BOOL   gCalledAppMainline = FALSE;
-
-static NSString *getApplicationName(void)
-{
-    const NSDictionary *dict;
-    NSString *appName = 0;
-
-    /* Determine the application name */
-    dict = (const NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
-    if (dict)
-        appName = [dict objectForKey: @"CFBundleName"];
-
-    if (![appName length])
-        appName = [[NSProcessInfo processInfo] processName];
-
-    return appName;
-}
-
-#if SDL_USE_NIB_FILE
-/* A helper category for NSString */
-@interface NSString (ReplaceSubString)
-- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
-@end
-#endif
-
-@interface SDLApplication : NSApplication
-@end
-
-@implementation SDLApplication
-/* Invoked from the Quit menu item */
-- (void)terminate:(id)sender
-{
-    /* Post a SDL_QUIT event */
-    SDL_Event event;
-    event.type = SDL_QUIT;
-    SDL_PushEvent(&event);
-}
-@end
-
-/* The main class of the application, the application's delegate */
-@implementation SDLMain
-
-/* Set the working directory to the .app's parent directory */
-- (void) setupWorkingDirectory:(BOOL)shouldChdir
-{
-    if (shouldChdir)
-    {
-        char parentdir[MAXPATHLEN];
-        CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
-        CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
-        if (CFURLGetFileSystemRepresentation(url2, 1, (UInt8 *)parentdir, MAXPATHLEN)) {
-            chdir(parentdir);   /* chdir to the binary app's parent */
-        }
-        CFRelease(url);
-        CFRelease(url2);
-    }
-}
-
-#if SDL_USE_NIB_FILE
-
-/* Fix menu to contain the real app name instead of "SDL App" */
-- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName
-{
-    NSRange aRange;
-    NSEnumerator *enumerator;
-    NSMenuItem *menuItem;
-
-    aRange = [[aMenu title] rangeOfString:@"SDL App"];
-    if (aRange.length != 0)
-        [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]];
-
-    enumerator = [[aMenu itemArray] objectEnumerator];
-    while ((menuItem = [enumerator nextObject]))
-    {
-        aRange = [[menuItem title] rangeOfString:@"SDL App"];
-        if (aRange.length != 0)
-            [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]];
-        if ([menuItem hasSubmenu])
-            [self fixMenu:[menuItem submenu] withAppName:appName];
-    }
-    [ aMenu sizeToFit ];
-}
-
-#else
-
-static void setApplicationMenu(void)
-{
-    /* warning: this code is very odd */
-    NSMenu *appleMenu;
-    NSMenuItem *menuItem;
-    NSString *title;
-    NSString *appName;
-
-    appName = getApplicationName();
-    appleMenu = [[NSMenu alloc] initWithTitle:@""];
-
-    /* Add menu items */
-    title = [@"About " stringByAppendingString:appName];
-    [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
-
-    [appleMenu addItem:[NSMenuItem separatorItem]];
-
-    title = [@"Hide " stringByAppendingString:appName];
-    [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
-
-    menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
-    [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
-
-    [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
-
-    [appleMenu addItem:[NSMenuItem separatorItem]];
-
-    title = [@"Quit " stringByAppendingString:appName];
-    [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
-
-
-    /* Put menu into the menubar */
-    menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
-    [menuItem setSubmenu:appleMenu];
-    [[NSApp mainMenu] addItem:menuItem];
-
-    /* Tell the application object that this is now the application menu */
-    [NSApp setAppleMenu:appleMenu];
-
-    /* Finally give up our references to the objects */
-    [appleMenu release];
-    [menuItem release];
-}
-
-/* Create a window menu */
-static void setupWindowMenu(void)
-{
-    NSMenu      *windowMenu;
-    NSMenuItem  *windowMenuItem;
-    NSMenuItem  *menuItem;
-
-    windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
-
-    /* "Minimize" item */
-    menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
-    [windowMenu addItem:menuItem];
-    [menuItem release];
-
-    /* Put menu into the menubar */
-    windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
-    [windowMenuItem setSubmenu:windowMenu];
-    [[NSApp mainMenu] addItem:windowMenuItem];
-
-    /* Tell the application object that this is now the window menu */
-    [NSApp setWindowsMenu:windowMenu];
-
-    /* Finally give up our references to the objects */
-    [windowMenu release];
-    [windowMenuItem release];
-}
-
-/* Replacement for NSApplicationMain */
-static void CustomApplicationMain (int argc, char **argv)
-{
-    NSAutoreleasePool   *pool = [[NSAutoreleasePool alloc] init];
-    SDLMain             *sdlMain;
-
-    /* Ensure the application object is initialised */
-    [SDLApplication sharedApplication];
-
-#ifdef SDL_USE_CPS
-    {
-        CPSProcessSerNum PSN;
-        /* Tell the dock about us */
-        if (!CPSGetCurrentProcess(&PSN))
-            if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
-                if (!CPSSetFrontProcess(&PSN))
-                    [SDLApplication sharedApplication];
-    }
-#endif /* SDL_USE_CPS */
-
-    /* Set up the menubar */
-    NSMenu *menu = [[NSMenu alloc] init];
-    [NSApp setMainMenu:menu];
-    setApplicationMenu();
-    setupWindowMenu();
-    [menu release];
-
-    /* Create SDLMain and make it the app delegate */
-    sdlMain = [[SDLMain alloc] init];
-    [NSApp setDelegate:sdlMain];
-
-    /* Start the main event loop */
-    [NSApp run];
-
-    [sdlMain release];
-    [pool release];
-}
-
-#endif
-
-
-/*
- * Catch document open requests...this lets us notice files when the app
- *  was launched by double-clicking a document, or when a document was
- *  dragged/dropped on the app's icon. You need to have a
- *  CFBundleDocumentsType section in your Info.plist to get this message,
- *  apparently.
- *
- * Files are added to gArgv, so to the app, they'll look like command line
- *  arguments. Previously, apps launched from the finder had nothing but
- *  an argv[0].
- *
- * This message may be received multiple times to open several docs on launch.
- *
- * This message is ignored once the app's mainline has been called.
- */
-- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
-{
-    const char *temparg;
-    size_t arglen;
-    char *arg;
-    char **newargv;
-
-    if (!gFinderLaunch)  /* MacOS is passing command line args. */
-        return FALSE;
-
-    if (gCalledAppMainline)  /* app has started, ignore this document. */
-        return FALSE;
-
-    temparg = [filename UTF8String];
-    arglen = SDL_strlen(temparg) + 1;
-    arg = (char *) SDL_malloc(arglen);
-    if (arg == NULL)
-        return FALSE;
-
-    newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2));
-    if (newargv == NULL)
-    {
-        SDL_free(arg);
-        return FALSE;
-    }
-    gArgv = newargv;
-
-    SDL_strlcpy(arg, temparg, arglen);
-    gArgv[gArgc++] = arg;
-    gArgv[gArgc] = NULL;
-    return TRUE;
-}
-
-
-/* Called when the internal event loop has just started running */
-- (void) applicationDidFinishLaunching: (NSNotification *) note
-{
-    int status;
-
-    /* Set the working directory to the .app's parent directory */
-    [self setupWorkingDirectory:gFinderLaunch];
-
-#if SDL_USE_NIB_FILE
-    /* Set the main menu to contain the real app name instead of "SDL App" */
-    [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()];
-#endif
-
-    /* Hand off to main application code */
-    gCalledAppMainline = TRUE;
-    status = SDL_main (gArgc, gArgv);
-
-    /* We're done, thank you for playing */
-    exit(status);
-}
-@end
-
-
-@implementation NSString (ReplaceSubString)
-
-- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
-{
-    unsigned int bufferSize;
-    unsigned int selfLen = [self length];
-    unsigned int aStringLen = [aString length];
-    unichar *buffer;
-    NSRange localRange;
-    NSString *result;
-
-    bufferSize = selfLen + aStringLen - aRange.length;
-    buffer = (unichar *)NSAllocateMemoryPages(bufferSize*sizeof(unichar));
-
-    /* Get first part into buffer */
-    localRange.location = 0;
-    localRange.length = aRange.location;
-    [self getCharacters:buffer range:localRange];
-
-    /* Get middle part into buffer */
-    localRange.location = 0;
-    localRange.length = aStringLen;
-    [aString getCharacters:(buffer+aRange.location) range:localRange];
-
-    /* Get last part into buffer */
-    localRange.location = aRange.location + aRange.length;
-    localRange.length = selfLen - localRange.location;
-    [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
-
-    /* Build output string */
-    result = [NSString stringWithCharacters:buffer length:bufferSize];
-
-    NSDeallocateMemoryPages(buffer, bufferSize);
-
-    return result;
-}
-
-@end
-
-
-
-#ifdef main
-#  undef main
-#endif
-
-
-/* Main entry point to executable - should *not* be SDL_main! */
-int main (int argc, char **argv)
-{
-    /* Copy the arguments into a global variable */
-    /* This is passed if we are launched by double-clicking */
-    if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
-        gArgv = (char **) SDL_malloc(sizeof (char *) * 2);
-        gArgv[0] = argv[0];
-        gArgv[1] = NULL;
-        gArgc = 1;
-        gFinderLaunch = YES;
-    } else {
-        int i;
-        gArgc = argc;
-        gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1));
-        for (i = 0; i <= argc; i++)
-            gArgv[i] = argv[i];
-        gFinderLaunch = NO;
-    }
-
-#if SDL_USE_NIB_FILE
-    [SDLApplication poseAsClass:[NSApplication class]];
-    NSApplicationMain (argc, argv);
-#else
-    CustomApplicationMain (argc, argv);
-#endif
-    return 0;
-}
-
--- a/hedgewars/uAI.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uAI.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -530,7 +530,7 @@
 FillBonuses(((Me^.State and gstAttacked) <> 0) and (not isInMultiShoot));
 
 SDL_LockMutex(ThreadLock);
-ThinkThread:= SDL_CreateThread(@Think{$IFDEF SDL2}, 'think'{$ENDIF}, Me);
+ThinkThread:= SDL_CreateThread(@Think, PChar('think'), Me);
 SDL_UnlockMutex(ThreadLock);
 end;
 
--- a/hedgewars/uChat.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uChat.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -21,6 +21,7 @@
 unit uChat;
 
 interface
+uses SDLh;
 
 procedure initModule;
 procedure freeModule;
@@ -28,12 +29,13 @@
 procedure CleanupInput;
 procedure AddChatString(s: shortstring);
 procedure DrawChat;
-procedure KeyPressChat(Key, Sym: Longword; Modifier: Word);
+procedure KeyPressChat(keysym: TSDL_Keysym);
 procedure SendHogSpeech(s: shortstring);
 procedure CopyToClipboard(var newContent: shortstring);
+procedure TextInput(var event: TSDL_TextInputEvent);
 
 implementation
-uses SDLh, uInputHandler, uTypes, uVariables, uCommands, uUtils, uTextures, uRender, uIO, uScript, uRenderUtils;
+uses uInputHandler, uTypes, uVariables, uCommands, uUtils, uTextures, uRender, uIO, uScript, uRenderUtils;
 
 const MaxStrIndex = 27;
       MaxInputStrLen = 200;
@@ -267,8 +269,6 @@
 inc(visibleCount)
 end;
 
-procedure CheckPasteBuffer(); forward;
-
 procedure UpdateInputLinePrefix();
 begin
 if liveLua then
@@ -302,7 +302,6 @@
 // draw chat input line first and under all other lines
 if (GameState = gsChat) and (InputStr.Tex <> nil) then
     begin
-    CheckPasteBuffer();
 
     if InputLinePrefix.Tex = nil then
         RenderChatLineTex(InputLinePrefix, InputLinePrefix.s);
@@ -571,9 +570,8 @@
 begin
     FreezeEnterKey;
     history:= 0;
-{$IFNDEF SDL2}
-    SDL_EnableKeyRepeat(0,0);
-{$ENDIF}
+    SDL_StopTextInput();
+    //SDL_EnableKeyRepeat(0,0);
     GameState:= gsGame;
     ResetKbd;
 end;
@@ -728,7 +726,8 @@
 
 procedure CopyToClipboard(var newContent: shortstring);
 begin
-    SendIPC(_S'y' + copy(newContent, 1, 253) + #0);
+    // SDL2 clipboard
+    SDL_SetClipboardText(Str2PChar(newContent));
 end;
 
 procedure CopySelectionToClipboard();
@@ -782,39 +781,41 @@
 end;
 
 procedure PasteFromClipboard();
+var clip: PChar;
 begin
-    SendIPC(_S'Y');
-end;
-
-procedure CheckPasteBuffer();
-begin
-    if Length(ChatPasteBuffer) > 0 then
+    // use SDL2 clipboard functions
+    if SDL_HasClipboardText() then
         begin
-        InsertIntoInputStr(ChatPasteBuffer);
-        ChatPasteBuffer:= '';
+        clip:= SDL_GetClipboardText();
+        // returns NULL if not enough memory for a copy of clipboard content 
+        if clip <> nil then
+            begin
+            InsertIntoInputStr(shortstring(clip));
+            SDL_free(Pointer(clip));
+            end;
         end;
 end;
 
-procedure KeyPressChat(Key, Sym: Longword; Modifier: Word);
-const firstByteMark: array[0..3] of byte = (0, $C0, $E0, $F0);
-      nonStateMask = (not (KMOD_NUM or KMOD_CAPS));
-var i, btw, index: integer;
-    utf8: shortstring;
-    action, selMode, ctrl, ctrlonly: boolean;
+procedure KeyPressChat(keysym: TSDL_Keysym);
+const nonStateMask = (not (KMOD_NUM or KMOD_CAPS));
+var i, index: integer;
+    selMode, ctrl, ctrlonly: boolean;
     skip: TCharSkip;
+    Scancode: TSDL_Scancode;
+    Modifier: Word;
 begin
+    Scancode:= keysym.scancode;
+    Modifier:= keysym.modifier;
+
     LastKeyPressTick:= RealTicks;
-    action:= true;
-
-    CheckPasteBuffer();
 
     selMode:= (modifier and (KMOD_LSHIFT or KMOD_RSHIFT)) <> 0;
     ctrl:= (modifier and (KMOD_LCTRL or KMOD_RCTRL)) <> 0;
     ctrlonly:= ctrl and ((modifier and nonStateMask and (not (KMOD_LCTRL or KMOD_RCTRL))) = 0);
     skip:= none;
 
-    case Sym of
-        SDLK_BACKSPACE:
+    case Scancode of
+        SDL_SCANCODE_BACKSPACE:
             begin
             if selectedPos < 0 then
                 begin
@@ -831,7 +832,7 @@
             DeleteSelected();
             UpdateCursorCoords();
             end;
-        SDLK_DELETE:
+        SDL_SCANCODE_DELETE:
             begin
             if selectedPos < 0 then
                 begin
@@ -848,7 +849,7 @@
             DeleteSelected();
             UpdateCursorCoords();
             end;
-        SDLK_ESCAPE:
+        SDL_SCANCODE_ESCAPE:
             begin
             if Length(InputStr.s) > 0 then
                 begin
@@ -857,7 +858,7 @@
                 end
             else CleanupInput
             end;
-        SDLK_RETURN, SDLK_KP_ENTER:
+        SDL_SCANCODE_RETURN, SDL_SCANCODE_KP_ENTER:
             begin
             if Length(InputStr.s) > 0 then
                 begin
@@ -867,10 +868,10 @@
                 end;
             CleanupInput
             end;
-        SDLK_UP, SDLK_DOWN:
+        SDL_SCANCODE_UP, SDL_SCANCODE_DOWN:
             begin
-            if (Sym = SDLK_UP) and (history < localLastStr) then inc(history);
-            if (Sym = SDLK_DOWN) and (history > 0) then dec(history);
+            if (Scancode = SDL_SCANCODE_UP) and (history < localLastStr) then inc(history);
+            if (Scancode = SDL_SCANCODE_DOWN) and (history > 0) then dec(history);
             index:= localLastStr - history + 1;
             if (index > localLastStr) then
                 begin
@@ -884,7 +885,7 @@
             ResetSelection();
             UpdateCursorCoords();
             end;
-        SDLK_HOME:
+        SDL_SCANCODE_HOME:
             begin
             if cursorPos > 0 then
                 begin
@@ -896,7 +897,7 @@
 
             UpdateCursorCoords();
             end;
-        SDLK_END:
+        SDL_SCANCODE_END:
             begin
             i:= Length(InputStr.s);
             if cursorPos < i then
@@ -909,7 +910,7 @@
 
             UpdateCursorCoords();
             end;
-        SDLK_LEFT:
+        SDL_SCANCODE_LEFT:
             begin
             if cursorPos > 0 then
                 begin
@@ -938,7 +939,7 @@
 
             UpdateCursorCoords();
             end;
-        SDLK_RIGHT:
+        SDL_SCANCODE_RIGHT:
             begin
             if cursorPos < Length(InputStr.s) then
                 begin
@@ -963,11 +964,12 @@
 
             UpdateCursorCoords();
             end;
-        SDLK_PAGEUP, SDLK_PAGEDOWN:
+        SDL_SCANCODE_PAGEUP, SDL_SCANCODE_PAGEDOWN:
             begin
             // ignore me!!!
             end;
-        SDLK_a:
+        // TODO: figure out how to determine those keys better
+        SDL_SCANCODE_a:
             begin
             // select all
             if ctrlonly then
@@ -978,18 +980,14 @@
                 cursorPos:= Length(InputStr.s);
                 UpdateCursorCoords();
                 end
-            else
-                action:= false;
             end;
-        SDLK_c:
+        SDL_SCANCODE_c:
             begin
             // copy
             if ctrlonly then
                 CopySelectionToClipboard()
-            else
-                action:= false;
             end;
-        SDLK_v:
+        SDL_SCANCODE_v:
             begin
             // paste
             if ctrlonly then
@@ -997,10 +995,8 @@
                 DeleteSelected();
                 PasteFromClipboard();
                 end
-            else
-                action:= false;
             end;
-        SDLK_x:
+        SDL_SCANCODE_x:
             begin
             // cut
             if ctrlonly then
@@ -1008,51 +1004,32 @@
                 CopySelectionToClipboard();
                 DeleteSelected();
                 end
-            else
-                action:= false;
             end;
-        else
-            action:= false;
         end;
-    if not action and (Key <> 0) then
-        begin
-        DeleteSelected();
+end;
 
-        if (Key < $80) then
-            btw:= 1
-        else if (Key < $800) then
-            btw:= 2
-        else if (Key < $10000) then
-            btw:= 3
-        else
-            btw:= 4;
-
-        utf8:= '';
+procedure TextInput(var event: TSDL_TextInputEvent);
+var s: shortstring;
+    l: byte;
+begin
+    DeleteSelected();
 
-        for i:= btw downto 2 do
-            begin
-            utf8:= char((Key or $80) and $BF) + utf8;
-            Key:= Key shr 6
-            end;
-
-        utf8:= char(Key or firstByteMark[Pred(btw)]) + utf8;
-
-        if Length(InputStr.s) + btw > MaxInputStrLen then
-            exit;
+    l:= 0;
+    while event.text[l] <> #0 do
+        begin
+        s[l + 1]:= event.text[l];
+        inc(l)
+        end;
 
-        // if speech bubble quotes are used as first input, add the closing quote and place cursor inbetween
-        if (Length(InputStr.s) = 0) and (Length(utf8) = 1) and (charIsForHogSpeech(utf8[1])) then
-            begin
-            InsertIntoInputStr(utf8);
-            InsertIntoInputStr(utf8);
-            cursorPos:= 1;
-            UpdateCursorCoords();
-            end
-        else
-            InsertIntoInputStr(utf8);
+    if l > 0 then
+        begin
+        if byte(InputStr.s[0]) + l > 240 then exit;
+        s[0]:= char(l);
+        InsertIntoInputStr(s);
         end
 end;
 
+
 procedure chChatMessage(var s: shortstring);
 begin
     AddChatString(s)
@@ -1098,9 +1075,9 @@
 begin
     s:= s; // avoid compiler hint
     GameState:= gsChat;
-{$IFNDEF SDL2}
-    SDL_EnableKeyRepeat(200,45);
-{$ENDIF}
+    SDL_StopTextInput();
+    SDL_StartTextInput();
+    //SDL_EnableKeyRepeat(200,45);
     if length(s) = 0 then
         SetLine(InputStr, '', true)
     else
@@ -1140,6 +1117,7 @@
 
     LastKeyPressTick:= 0;
     ResetCursor();
+    SDL_StopTextInput();
 end;
 
 procedure freeModule;
--- a/hedgewars/uCollisions.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uCollisions.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -211,10 +211,15 @@
     i:= y + Gear^.Radius * 2 - 2;
     repeat
         if (y and LAND_HEIGHT_MASK) = 0 then
-            if Land[y, x] and Gear^.CollisionMask > 255 then
-                exit(Land[y, x] and Gear^.CollisionMask)
-            else if Land[y, x] and Gear^.CollisionMask <> 0 then
-                pixel:= Land[y, x] and Gear^.CollisionMask;
+            begin
+            if Land[y, x] and Gear^.CollisionMask <> 0 then
+                begin
+                if Land[y, x] and Gear^.CollisionMask > 255 then
+                    exit(Land[y, x] and Gear^.CollisionMask)
+                else
+                    pixel:= Land[y, x] and Gear^.CollisionMask;
+                end;
+            end;
     inc(y)
     until (y > i);
     end;
@@ -274,10 +279,12 @@
     repeat
     if (x and LAND_WIDTH_MASK) = 0 then
         if Land[y, x] > 0 then
+            begin
             if Land[y, x] and Gear^.CollisionMask > 255 then
                 exit(Land[y, x] and Gear^.CollisionMask)
-            else if Land[y, x] <> 0 then
+            else // if Land[y, x] <> 0 then
                 pixel:= Land[y, x] and Gear^.CollisionMask;
+            end;
     inc(x)
     until (x > i);
     end;
--- a/hedgewars/uDebug.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uDebug.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -24,7 +24,7 @@
 
 procedure OutError(Msg: shortstring; isFatalError: boolean);
 procedure TryDo(Assert: boolean; Msg: shortstring; isFatal: boolean); inline;
-procedure SDLTry(Assert: boolean; isFatal: boolean);
+procedure SDLTry(Assert: boolean; Msg: shortstring; isFatal: boolean);
 
 implementation
 uses SDLh, uConsole, uCommands, uConsts;
@@ -42,13 +42,13 @@
     OutError(Msg, isFatal)
 end;
 
-procedure SDLTry(Assert: boolean; isFatal: boolean);
+procedure SDLTry(Assert: boolean; Msg: shortstring; isFatal: boolean);
 var s: shortstring;
 begin
 if not Assert then
     begin
     s:= SDL_GetError();
-    OutError(s, isFatal)
+    OutError(Msg + ': ' + s, isFatal)
     end
 end;
 
--- a/hedgewars/uFLIPC.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uFLIPC.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -192,14 +192,14 @@
 begin
     callbackPointerF:= p;
     callbackFunctionF:= f;
-    callbackListenerThreadF:= SDL_CreateThread(@engineListener{$IFDEF SDL2}, 'engineListener'{$ENDIF}, nil);
+    callbackListenerThreadF:= SDL_CreateThread(@engineListener, 'engineListener', nil);
 end;
 
 procedure registerNetCallback(p: pointer; f: TIPCCallback);
 begin
     callbackPointerN:= p;
     callbackFunctionN:= f;
-    callbackListenerThreadN:= SDL_CreateThread(@netListener{$IFDEF SDL2}, 'netListener'{$ENDIF}, nil);
+    callbackListenerThreadN:= SDL_CreateThread(@netListener, 'netListener', nil);
 end;
 
 procedure initIPC;
@@ -224,8 +224,8 @@
 
 procedure freeIPC;
 begin
-    SDL_KillThread(callbackListenerThreadF);
-    SDL_KillThread(callbackListenerThreadN);
+    //FIXME SDL_KillThread(callbackListenerThreadF);
+    //FIXME SDL_KillThread(callbackListenerThreadN);
     SDL_DestroyMutex(mutFrontend);
     SDL_DestroyMutex(mutEngine);
     SDL_DestroyMutex(mutNet);
--- a/hedgewars/uFLNet.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uFLNet.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -218,7 +218,7 @@
     if SDLNet_ResolveHost(ipaddr, PChar('netserver.hedgewars.org'), 46631) = 0 then
         sock:= SDLNet_TCP_Open(ipaddr);
 
-    SDL_CreateThread(@netWriter{$IFDEF SDL2}, 'netWriter'{$ENDIF}, sock);
+    SDL_CreateThread(@netWriter, 'netWriter', sock);
 
     repeat
         c:= getNextChar;
@@ -276,7 +276,7 @@
     state.l:= 0;
     state.netState:= netConnecting;
 
-    netReaderThread:= SDL_CreateThread(@netReader{$IFDEF SDL2}, 'netReader'{$ENDIF}, nil);
+    netReaderThread:= SDL_CreateThread(@netReader, 'netReader', nil);
 end;
 
 procedure initModule;
--- a/hedgewars/uGears.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uGears.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -320,6 +320,7 @@
                     Ammoz[amTardis].Probability:= 0;
                     end;
                 AddCaption(trmsg[sidSuddenDeath], cWhiteColor, capgrpGameState);
+                ScriptCall('onSuddenDeath');
                 playSound(sndSuddenDeath);
                 StopMusic;
                 if SDMusicFN <> '' then PlayMusic
--- a/hedgewars/uGearsHandlersMess.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uGearsHandlersMess.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -343,7 +343,7 @@
 // might need some testing/adjustments - just to avoid projectiles to fly forever (accelerated by wind/skips)
     if (gX < min(LAND_WIDTH div -2, -2048))
     or (gX > max(LAND_WIDTH * 3 div 2, 6144)) then
-        Gear^.State := Gear^.State or gstCollision;
+        Gear^.Message := Gear^.Message or gmDestroy;
 
     if Gear^.dY.isNegative then
         begin
@@ -464,11 +464,12 @@
     if Gear^.AdvBounce > 1 then
         dec(Gear^.AdvBounce);
 
-    if isFalling then
-        begin
-        if Gear^.State and gstNoGravity = 0 then
-            Gear^.dY := Gear^.dY + cGravity;
-        if (GameFlags and gfMoreWind) <> 0 then
+    if isFalling and (Gear^.State and gstNoGravity = 0) then
+        begin
+        Gear^.dY := Gear^.dY + cGravity;
+        if (GameFlags and gfMoreWind <> 0) and 
+           ((xland or land) = 0) and
+           ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) > _0_02.QWordValue) then
             Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density
         end;
 
@@ -482,10 +483,7 @@
         Gear^.State := Gear^.State or gstMoving;
 
     if ((xland or land) and lfBouncy <> 0) and (Gear^.dX.QWordValue < _0_15.QWordValue) and (Gear^.dY.QWordValue < _0_15.QWordValue) then
-        begin
         Gear^.State := Gear^.State or gstCollision;
-        AddFileLog('no more bounce for you!');
-        end;
 
     if ((xland or land) and lfBouncy <> 0) and (Gear^.Radius >= 3) and
        ((Gear^.dX.QWordValue > _0_15.QWordValue) or (Gear^.dY.QWordValue > _0_15.QWordValue)) then
@@ -1094,6 +1092,7 @@
     AllInactive := false;
     Gear^.X := Gear^.X + Gear^.dX;
     Gear^.Y := Gear^.Y + Gear^.dY;
+    WorldWrap(Gear);
     Gear^.dY := Gear^.dY + cGravity;
     CheckGearDrowning(Gear);
     CheckCollision(Gear);
@@ -1959,7 +1958,7 @@
     if land = 0 then land:= TestCollisionYwithGear(Gear,-2);
     if land = 0 then land:= TestCollisionXwithGear(Gear,-2);
     if land = 0 then land:= TestCollisionYwithGear(Gear, 2);
-    if (land <> 0) and (land and lfBouncy = 0) then
+    if (land <> 0) and ((land and lfBouncy = 0) or ((Gear^.State and gstMoving) = 0)) then
         begin
         if ((Gear^.State and gstMoving) <> 0) or (not isZero(Gear^.dX)) or (not isZero(Gear^.dY)) then
             begin
@@ -2649,7 +2648,11 @@
 
     AfterAttack;
 
-    HHGear^.State := HHGear^.State and (not (gstAttacking or gstAttacked or gstMoving));
+    // make sure hog doesn't end up facing in wrong direction due to high jump
+    if (HHGear^.State and gstHHHJump) <> 0 then
+        HHGear^.dX.isNegative := (not HHGear^.dX.isNegative);
+
+    HHGear^.State := HHGear^.State and (not (gstAttacking or gstAttacked or gstMoving or gstHHJumping or gstHHHJump));
     HHGear^.Message := HHGear^.Message and (not gmAttack);
 
     Gear^.doStep := @doStepParachuteWork;
@@ -2675,7 +2678,7 @@
             //4: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtWaterMelon, 0, cBombsSpeed *
             //                 Gear^.Tag, _0, 5000);
             end;
-        Gear^.dX := Gear^.dX + int2hwFloat(30 * Gear^.Tag);
+        Gear^.dX := Gear^.dX + int2hwFloat(Gear^.Damage * Gear^.Tag);
         if CheckCoordInWater(hwRound(Gear^.X), hwRound(Gear^.Y)) then
             FollowGear^.State:= FollowGear^.State or gstSubmersible;
         StopSoundChan(Gear^.SoundChannel, 4000);
@@ -2708,7 +2711,7 @@
         end;
 
     Gear^.Y := int2hwFloat(topY-300);
-    Gear^.dX := int2hwFloat(Gear^.Target.X - 5 * Gear^.Tag * 15);
+    Gear^.dX := int2hwFloat(Gear^.Target.X) - int2hwFloat(Gear^.Tag * Gear^.Health * Gear^.Damage) / 2;
 
     // calcs for Napalm Strike, so that it will hit the target (without wind at least :P)
     if (Gear^.State = 2) then
@@ -2718,7 +2721,6 @@
             Gear^.dX := Gear^.dX - cBombsSpeed * hwSqrt((int2hwFloat(Gear^.Target.Y) - Gear^.Y) * 2 /
                 cGravity) * Gear^.Tag;
 
-    Gear^.Health := 6;
     Gear^.doStep := @doStepAirAttackWork;
     Gear^.SoundChannel := LoopSound(sndPlane, 4000);
 
@@ -3535,7 +3537,7 @@
 begin
     AllInactive := false;
 
-    if (Gear^.State and gsttmpFlag) = 0 then
+    if (Gear^.State and gsttmpFlag = 0) and (GameFlags and gfMoreWind = 0) then
         Gear^.dX := Gear^.dX + cWindSpeed;
 
     oldDx := Gear^.dX;
@@ -3677,7 +3679,14 @@
     FollowGear := Gear;
 
     if Gear^.Timer > 0 then
+        begin
+        if Gear^.Timer = 1 then
+            begin
+            StopSoundChan(Gear^.SoundChannel);
+            Gear^.SoundChannel:= -1;
+            end;
         dec(Gear^.Timer);
+        end;
 
     fChanged := false;
     if (HHGear = nil) or ((HHGear^.State and gstHHDriven) = 0) or (Gear^.Timer = 0) then
@@ -5191,7 +5200,9 @@
 ////////////////////////////////////////////////////////////////////////////////
 procedure doStepPoisonCloud(Gear: PGear);
 begin
-    WorldWrap(Gear);
+    // don't bounce
+    if WorldEdge <> weBounce then
+        WorldWrap(Gear);
     if Gear^.Timer = 0 then
         begin
         DeleteGear(Gear);
@@ -5247,13 +5258,12 @@
                         d:= 2
                     else
                         d:= 3;
-                    // always round up
-                    if dmg mod d > 0 then
-                        dmg:= dmg div d + 1
-                    else
-                        dmg:= dmg div d;
-
-                    ApplyDamage(tmp, CurrentHedgehog, dmg, dsUnknown);
+
+                    // always rounding down
+                    dmg:= dmg div d;
+
+                    if dmg > 0 then
+                        ApplyDamage(tmp, CurrentHedgehog, dmg, dsUnknown);
                     end;
                 end;
 
@@ -5423,7 +5433,7 @@
         for i:= 0 to graves.size - 1 do
             if graves.ar^[i]^.Health > 0 then
                 begin
-                resgear := AddGear(hwRound(graves.ar^[i]^.X), hwRound(graves.ar^[i]^.Y), gtHedgehog, gstWait, _0, _0, 0);
+                resgear := AddGear(hwRound(graves.ar^[i]^.X), hwRound(graves.ar^[i]^.Y), gtHedgehog, gstWait, _0, _0, 0,graves.ar^[i]^.Pos);
                 resgear^.Hedgehog := graves.ar^[i]^.Hedgehog;
                 resgear^.Health := graves.ar^[i]^.Health;
                 PHedgehog(graves.ar^[i]^.Hedgehog)^.Gear := resgear;
@@ -5785,9 +5795,16 @@
 All these effects assume the ray's angle is not changed and that the target type was unchanged over a number of ticks.  This is a simplifying assumption for "gun was applying freezing effect to the same target".
   * When fired at water a layer of ice textured land is added above the water.
   * When fired at non-ice land (land and lfLandMask and not lfIce) the land is overlaid with a thin layer of ice textured land around that point (say, 1 or 2px into land, 1px above). For attractiveness, a slope would probably be needed.
-  * When fired at a hog (land and $00FF <> 0), while the hog is targetted, the hog's state is set to frozen.  As long as the gun is on the hog, a frozen hog sprite creeps up from the feet to the head.  If the effect is interrupted before reaching the top, the freezing state is cleared.
-A frozen hog will animate differently.  To be decided, but possibly in a similar fashion to a grave when it comes to explosions.  The hog might (possibly) not be damaged by explosions.  This might make freezing potentially useful for friendlies in a bad position.  It might be better to allow damage though.
-A frozen hog stays frozen for a certain number of turns. Each turn the frozen overlay becomes fainter, until it fades and the hog animates normally again.
+  * When fired at a hog (land and $00FF <> 0), while the hog is targetted, the hog's state is set to frozen.
+    As long as the gun is on the hog, a frozen hog sprite creeps up from the feet to the head.
+    If the effect is interrupted before reaching the top, the freezing state is cleared.
+A frozen hog will animate differently.
+    To be decided, but possibly in a similar fashion to a grave when it comes to explosions.
+    The hog might (possibly) not be damaged by explosions.
+    This might make freezing potentially useful for friendlies in a bad position.
+    It might be better to allow damage though.
+A frozen hog stays frozen for a certain number of turns.
+    Each turn the frozen overlay becomes fainter, until it fades and the hog animates normally again.
 *)
 
 
--- a/hedgewars/uGearsHandlersRope.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uGearsHandlersRope.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -42,7 +42,8 @@
         OutError('ERROR: doStepRopeAfterAttack called while HHGear = nil', IsNilHHFatal);
         DeleteGear(Gear);
         exit()
-        end;
+        end
+    else if not CurrentTeam^.ExtDriven and (FollowGear <> nil) then FollowGear := HHGear;
 
     tX:= HHGear^.X;
     if WorldWrap(HHGear) and (WorldEdge = weWrap) and
@@ -137,7 +138,8 @@
         OutError('ERROR: doStepRopeWork called while HHGear = nil', IsNilHHFatal);
         DeleteGear(Gear);
         exit()
-        end;
+        end
+    else if not CurrentTeam^.ExtDriven and (FollowGear <> nil) then FollowGear := HHGear;
 
     if ((HHGear^.State and gstHHDriven) = 0) or
         (CheckGearDrowning(HHGear)) or (Gear^.PortalCounter <> 0) then
@@ -425,6 +427,7 @@
     HHGear: PGear;
     tx, ty, tt: hwFloat;
 begin
+    
     Gear^.X := Gear^.X - Gear^.dX;
     Gear^.Y := Gear^.Y - Gear^.dY;
     Gear^.Elasticity := Gear^.Elasticity + _1;
@@ -435,7 +438,8 @@
         OutError('ERROR: doStepRopeAttach called while HHGear = nil', IsNilHHFatal);
         DeleteGear(Gear);
         exit()
-        end;
+        end
+    else if not CurrentTeam^.ExtDriven and (FollowGear <> nil) then FollowGear := HHGear;
 
     DeleteCI(HHGear);
 
--- a/hedgewars/uGearsHedgehog.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uGearsHedgehog.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -451,7 +451,7 @@
             if CurAmmoType = amAirMine then newGear^.Hedgehog:= nil;
 
             if ((CurAmmoType = amMine) or (CurAmmoType = amSMine) or (CurAmmoType = amAirMine)) and (GameFlags and gfInfAttack <> 0) then
-                newGear^.FlightTime:= GameTicks + 1000
+                newGear^.FlightTime:= GameTicks + min(TurnTimeLeft,1000)
             else if CurAmmoType = amDrill then
                 newGear^.FlightTime:= GameTicks + 250;
             if Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then
@@ -572,6 +572,7 @@
 procedure doStepHedgehogDead(Gear: PGear);
 const frametime = 200;
       timertime = frametime * 6;
+var grave:  PGear;
 begin
 if Gear^.Hedgehog^.Unplaced then
     exit;
@@ -587,7 +588,10 @@
     Gear^.Hedgehog^.Effects[heFrozen]:= 0;
     Gear^.State:= Gear^.State or gstNoDamage;
     doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, CurrentHedgehog, EXPLAutoSound);
-    AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtGrave, 0, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog;
+    grave:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtGrave, 0, _0, _0, 0);
+    grave^.Hedgehog:= Gear^.Hedgehog;
+    grave^.Pos:= Gear^.uid;
+    
     DeleteGear(Gear);
     SetAllToActive
     end
@@ -906,6 +910,7 @@
         end;
     Gear^.State:= Gear^.State or gstMoving;
     if (Gear^.State and gstHHDriven <> 0) and
+       (FollowGear <> nil) and
        (not CurrentTeam^.ExtDriven) and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > _0_003) then
         begin
         // TODO: why so aggressive at setting FollowGear when falling?
--- a/hedgewars/uGearsList.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uGearsList.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -23,6 +23,7 @@
 uses uFloat, uTypes, SDLh;
 
 function  AddGear(X, Y: LongInt; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer: LongWord): PGear;
+function  AddGear(X, Y: LongInt; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer, newUid: LongWord): PGear;
 procedure DeleteGear(Gear: PGear);
 procedure InsertGearToList(Gear: PGear);
 procedure RemoveGearFromList(Gear: PGear);
@@ -164,11 +165,16 @@
 
 
 function AddGear(X, Y: LongInt; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer: LongWord): PGear;
+begin
+AddGear:= AddGear(X, Y, Kind, State, dX, dY, Timer, 0);
+end;
+function AddGear(X, Y: LongInt; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer, newUid: LongWord): PGear;
 var gear: PGear;
     //c: byte;
     cakeData: PCakeData;
 begin
-inc(GCounter);
+if newUid = 0 then
+    inc(GCounter);
 
 AddFileLog('AddGear: #' + inttostr(GCounter) + ' (' + inttostr(x) + ',' + inttostr(y) + '), d(' + floattostr(dX) + ',' + floattostr(dY) + ') type = ' + EnumToStr(Kind));
 
@@ -186,7 +192,9 @@
 gear^.doStep:= doStepHandlers[Kind];
 gear^.CollisionIndex:= -1;
 gear^.Timer:= Timer;
-gear^.uid:= GCounter;
+if newUid = 0 then
+     gear^.uid:= GCounter
+else gear^.uid:= newUid;
 gear^.SoundChannel:= -1;
 gear^.ImpactSound:= sndNone;
 gear^.Density:= _1;
@@ -466,6 +474,8 @@
                 gear^.Tag:= Y
                 end;
    gtAirAttack: begin
+                gear^.Health:= 6;
+                gear^.Damage:= 30;
                 gear^.Z:= cHHZ+2;
                 gear^.Tint:= gear^.Hedgehog^.Team^.Clan^.Color shl 8 or $FF
                 end;
--- a/hedgewars/uGearsRender.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uGearsRender.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -728,7 +728,7 @@
                 amHellishBomb: DrawSpriteRotated(sprHandHellish, hx, hy, sign, aangle);
                 amGasBomb: DrawSpriteRotated(sprHandCheese, hx, hy, sign, aangle);
                 amMine: DrawSpriteRotated(sprHandMine, hx, hy, sign, aangle);
-                amAirMine: DrawSpriteRotated(sprHandMine, hx, hy, sign, aangle);
+                amAirMine: DrawSpriteRotated(sprHandAirMine, hx, hy, sign, aangle);
                 amSMine: DrawSpriteRotated(sprHandSMine, hx, hy, sign, aangle);
                 amKnife: DrawSpriteRotatedF(sprHandKnife, hx, hy, 0, sign, aangle);
                 amSeduction: begin
--- a/hedgewars/uGearsUtils.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uGearsUtils.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -829,7 +829,7 @@
 
 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean);
 var x: LongInt;
-    y, sy: LongInt;
+    y, sy, dir: LongInt;
     ar: array[0..1023] of TPoint;
     ar2: array[0..2047] of TPoint;
     temp: TPoint;
@@ -850,9 +850,10 @@
     delta:= LAND_WIDTH div 16;
     cnt2:= 0;
     repeat
-        x:= Left + max(LAND_WIDTH div 2048, LongInt(GetRandom(Delta)));
+        if GetRandom(2) = 0 then dir:= -1 else dir:= 1;
+        x:= max(LAND_WIDTH div 2048, LongInt(GetRandom(Delta)));
+        if dir = 1 then x:= Left + x else x:= Right - x; 
         repeat
-            inc(x, Delta);
             cnt:= 0;
             y:= min(1024, topY) - Gear^.Radius shl 1;
             while y < cWaterLine do
@@ -901,9 +902,10 @@
                     ar2[cnt2].x:= x;
                     ar2[cnt2].y:= y;
                     inc(cnt2)
-                    end
-                end
-        until (x + Delta > Right);
+                    end;
+                end;
+            inc(x, Delta*dir)
+        until ((dir = 1) and (x > Right)) or ((dir = -1) and (x < Left));
 
         dec(Delta, 60)
     until (cnt2 > 0) or (Delta < 70);
--- a/hedgewars/uIO.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uIO.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -143,7 +143,6 @@
              ParseChatCommand('chatmsg ' + #4, s, 2)
           else
              isProcessed:= false;
-     'Y': ChatPasteBuffer:= copy(s, 2, Length(s) - 1);
      else
         isProcessed:= false;
      end;
--- a/hedgewars/uInputHandler.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uInputHandler.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -30,6 +30,7 @@
 //procedure MaskModifier(var code: LongInt; modifier: LongWord);
 procedure MaskModifier(Modifier: shortstring; var code: LongInt);
 procedure ProcessMouse(event: TSDL_MouseButtonEvent; ButtonDown: boolean);
+procedure ProcessMouseWheel(x, y: LongInt);
 procedure ProcessKey(event: TSDL_KeyboardEvent); inline;
 procedure ProcessKey(code: LongInt; KeyDown: boolean);
 
@@ -82,8 +83,8 @@
 var code: LongInt;
 begin
     name:= LowerCase(name);
-    code:= cKeyMaxIndex;
-    while (code > 0) and (KeyNames[code] <> name) do dec(code);
+    code:= 0;
+    while (code <= cKeyMaxIndex) and (KeyNames[code] <> name) do inc(code);
 
     MaskModifier(Modifier, code);
     KeyNameToCode:= code;
@@ -168,7 +169,13 @@
 
 if CurrentBinds[code][0] <> #0 then
     begin
-    if (code > 3) and KeyDown and (not ((CurrentBinds[code] = 'put')) or (CurrentBinds[code] = 'ammomenu') or (CurrentBinds[code] = '+cur_u') or (CurrentBinds[code] = '+cur_d') or (CurrentBinds[code] = '+cur_l') or (CurrentBinds[code] = '+cur_r')) and (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) then bShowAmmoMenu:= false;
+    if (code < cKeyMaxIndex - 2) // means not mouse buttons
+        and KeyDown
+        and (not ((CurrentBinds[code] = 'put')) or (CurrentBinds[code] = 'ammomenu') or (CurrentBinds[code] = '+cur_u') or (CurrentBinds[code] = '+cur_d') or (CurrentBinds[code] = '+cur_l') or (CurrentBinds[code] = '+cur_r')) 
+        and (CurrentTeam <> nil) 
+        and (not CurrentTeam^.ExtDriven) 
+        then bShowAmmoMenu:= false;
+
     if KeyDown then
         begin
         Trusted:= Trusted and (not isPaused); //releasing keys during pause should be allowed on the other hand
@@ -203,25 +210,36 @@
 procedure ProcessKey(event: TSDL_KeyboardEvent); inline;
 var code: LongInt;
 begin
-    code:= event.keysym.sym;
-    //MaskModifier(code, event.keysym.modifier);
+    // TODO
+    code:= LongInt(event.keysym.scancode);
+    //writelntoconsole('[KEY] '+inttostr(code)+ ' -> ''' +KeyNames[code] + ''', type = '+inttostr(event.type_));
     ProcessKey(code, event.type_ = SDL_KEYDOWN);
 end;
 
 procedure ProcessMouse(event: TSDL_MouseButtonEvent; ButtonDown: boolean);
 begin
-case event.button of
-    SDL_BUTTON_LEFT:
-        ProcessKey(KeyNameToCode('mousel'), ButtonDown);
-    SDL_BUTTON_MIDDLE:
-        ProcessKey(KeyNameToCode('mousem'), ButtonDown);
-    SDL_BUTTON_RIGHT:
-        ProcessKey(KeyNameToCode('mouser'), ButtonDown);
-    SDL_BUTTON_WHEELDOWN:
-        ProcessKey(KeyNameToCode('wheeldown'), ButtonDown);
-    SDL_BUTTON_WHEELUP:
-        ProcessKey(KeyNameToCode('wheelup'), ButtonDown);
-    end;
+    //writelntoconsole('[MOUSE] '+inttostr(event.button));
+    case event.button of
+        SDL_BUTTON_LEFT:
+            ProcessKey(KeyNameToCode('mousel'), ButtonDown);
+        SDL_BUTTON_MIDDLE:
+            ProcessKey(KeyNameToCode('mousem'), ButtonDown);
+        SDL_BUTTON_RIGHT:
+            ProcessKey(KeyNameToCode('mouser'), ButtonDown);
+        SDL_BUTTON_WHEELDOWN:
+            ProcessKey(KeyNameToCode('wheeldown'), ButtonDown);
+        SDL_BUTTON_WHEELUP:
+            ProcessKey(KeyNameToCode('wheelup'), ButtonDown);
+        end;
+end;
+
+procedure ProcessMouseWheel(x, y: LongInt);
+begin
+    //writelntoconsole('[MOUSEWHEEL] '+inttostr(x)+', '+inttostr(y));
+    if y > 0 then
+        ProcessKey(KeyNameToCode('wheelup'), true)
+    else if y < 0 then
+        ProcessKey(KeyNameToCode('wheeldown'), true);
 end;
 
 procedure ResetKbd;
@@ -232,125 +250,131 @@
         ProcessKey(t, False);
 end;
 
+
+procedure InitDefaultBinds;
+var i: Longword;
+begin
+    DefaultBinds[KeyNameToCode('escape')]:= 'quit';
+    DefaultBinds[KeyNameToCode(_S'`')]:= 'history';
+    DefaultBinds[KeyNameToCode('delete')]:= 'rotmask';
+
+    //numpad
+    //DefaultBinds[265]:= '+volup';
+    //DefaultBinds[256]:= '+voldown';
+
+    DefaultBinds[KeyNameToCode(_S'0')]:= '+volup';
+    DefaultBinds[KeyNameToCode(_S'9')]:= '+voldown';
+    DefaultBinds[KeyNameToCode(_S'8')]:= 'mute';
+    DefaultBinds[KeyNameToCode(_S'c')]:= 'capture';
+    DefaultBinds[KeyNameToCode(_S'r')]:= 'record';
+    DefaultBinds[KeyNameToCode(_S'h')]:= 'findhh';
+    DefaultBinds[KeyNameToCode(_S'p')]:= 'pause';
+    DefaultBinds[KeyNameToCode(_S's')]:= '+speedup';
+    DefaultBinds[KeyNameToCode(_S't')]:= 'chat';
+    DefaultBinds[KeyNameToCode(_S'y')]:= 'confirm';
+
+    DefaultBinds[KeyNameToCode('mousem')]:= 'zoomreset';
+    DefaultBinds[KeyNameToCode('wheelup')]:= 'zoomin';
+    DefaultBinds[KeyNameToCode('wheeldown')]:= 'zoomout';
+
+    DefaultBinds[KeyNameToCode('f12')]:= 'fullscr';
+
+
+    DefaultBinds[KeyNameToCode('mousel')]:= '/put';
+    DefaultBinds[KeyNameToCode('mouser')]:= 'ammomenu';
+    DefaultBinds[KeyNameToCode('backspace')]:= 'hjump';
+    DefaultBinds[KeyNameToCode('tab')]:= 'switch';
+    DefaultBinds[KeyNameToCode('return')]:= 'ljump';
+    DefaultBinds[KeyNameToCode('space')]:= '+attack';
+    DefaultBinds[KeyNameToCode('up')]:= '+up';
+    DefaultBinds[KeyNameToCode('down')]:= '+down';
+    DefaultBinds[KeyNameToCode('left')]:= '+left';
+    DefaultBinds[KeyNameToCode('right')]:= '+right';
+    DefaultBinds[KeyNameToCode('left_shift')]:= '+precise';
+
+
+    DefaultBinds[KeyNameToCode('j0a0u')]:= '+left';
+    DefaultBinds[KeyNameToCode('j0a0d')]:= '+right';
+    DefaultBinds[KeyNameToCode('j0a1u')]:= '+up';
+    DefaultBinds[KeyNameToCode('j0a1d')]:= '+down';
+    for i:= 1 to 10 do DefaultBinds[KeyNameToCode('f'+IntToStr(i))]:= 'slot '+IntToStr(i);
+    for i:= 1 to 5  do DefaultBinds[KeyNameToCode(IntToStr(i))]:= 'timer '+IntToStr(i);
+
+    loadBinds('dbind', cPathz[ptData] + '/settings.ini');
+end;
+
+
 procedure InitKbdKeyTable;
 var i, j, k, t: LongInt;
     s: string[15];
 begin
-//TODO in sdl13 this overrides some values (A and B) change indices to some other values at the back perhaps?
-KeyNames[1]:= 'mousel';
-KeyNames[2]:= 'mousem';
-KeyNames[3]:= 'mouser';
-KeyNames[4]:= 'wheelup';
-KeyNames[5]:= 'wheeldown';
+    KeyNames[cKeyMaxIndex    ]:= 'mousel';
+    KeyNames[cKeyMaxIndex - 1]:= 'mousem';
+    KeyNames[cKeyMaxIndex - 2]:= 'mouser';
+    KeyNames[cKeyMaxIndex - 3]:= 'wheelup';
+    KeyNames[cKeyMaxIndex - 4]:= 'wheeldown';
 
-for i:= 6 to cKeyMaxIndex do
-    begin
-    s:= shortstring(sdl_getkeyname(i));
-    //WriteLnToConsole('uInputHandler - ' + IntToStr(i) + ': ' + s + ' ' + IntToStr(cKeyMaxIndex));
-    if s = 'unknown key' then KeyNames[i]:= ''
-    else
+    for i:= 0 to cKeyMaxIndex - 5 do
         begin
+        s:= shortstring(SDL_GetScancodeName(TSDL_Scancode(i)));
+
         for t:= 1 to Length(s) do
             if s[t] = ' ' then
                 s[t]:= '_';
         KeyNames[i]:= LowerCase(s)
         end;
-    end;
 
 
-// get the size of keyboard array
-SDL_GetKeyState(@k);
+    // get the size of keyboard array
+    SDL_GetKeyboardState(@k);
 
-// Controller(s)
-for j:= 0 to Pred(ControllerNumControllers) do
-    begin
-    for i:= 0 to Pred(ControllerNumAxes[j]) do
+    // Controller(s)
+    for j:= 0 to Pred(ControllerNumControllers) do
         begin
-        keynames[k + 0]:= 'j' + IntToStr(j) + 'a' + IntToStr(i) + 'u';
-        keynames[k + 1]:= 'j' + IntToStr(j) + 'a' + IntToStr(i) + 'd';
-        inc(k, 2);
-        end;
-    for i:= 0 to Pred(ControllerNumHats[j]) do
-        begin
-        keynames[k + 0]:= 'j' + IntToStr(j) + 'h' + IntToStr(i) + 'u';
-        keynames[k + 1]:= 'j' + IntToStr(j) + 'h' + IntToStr(i) + 'r';
-        keynames[k + 2]:= 'j' + IntToStr(j) + 'h' + IntToStr(i) + 'd';
-        keynames[k + 3]:= 'j' + IntToStr(j) + 'h' + IntToStr(i) + 'l';
-        inc(k, 4);
-        end;
-    for i:= 0 to Pred(ControllerNumButtons[j]) do
-        begin
-        keynames[k]:= 'j' + IntToStr(j) + 'b' + IntToStr(i);
-        inc(k, 1);
+        for i:= 0 to Pred(ControllerNumAxes[j]) do
+            begin
+            KeyNames[k + 0]:= 'j' + IntToStr(j) + 'a' + IntToStr(i) + 'u';
+            KeyNames[k + 1]:= 'j' + IntToStr(j) + 'a' + IntToStr(i) + 'd';
+            inc(k, 2);
+            end;
+        for i:= 0 to Pred(ControllerNumHats[j]) do
+            begin
+            KeyNames[k + 0]:= 'j' + IntToStr(j) + 'h' + IntToStr(i) + 'u';
+            KeyNames[k + 1]:= 'j' + IntToStr(j) + 'h' + IntToStr(i) + 'r';
+            KeyNames[k + 2]:= 'j' + IntToStr(j) + 'h' + IntToStr(i) + 'd';
+            KeyNames[k + 3]:= 'j' + IntToStr(j) + 'h' + IntToStr(i) + 'l';
+            inc(k, 4);
+            end;
+        for i:= 0 to Pred(ControllerNumButtons[j]) do
+            begin
+            KeyNames[k]:= 'j' + IntToStr(j) + 'b' + IntToStr(i);
+            inc(k, 1);
+            end;
         end;
-    end;
 
-DefaultBinds[KeyNameToCode('escape')]:= 'quit';
-DefaultBinds[KeyNameToCode(_S'`')]:= 'history';
-DefaultBinds[KeyNameToCode('delete')]:= 'rotmask';
-
-//numpad
-//DefaultBinds[265]:= '+volup';
-//DefaultBinds[256]:= '+voldown';
-
-DefaultBinds[KeyNameToCode(_S'0')]:= '+volup';
-DefaultBinds[KeyNameToCode(_S'9')]:= '+voldown';
-DefaultBinds[KeyNameToCode(_S'8')]:= 'mute';
-DefaultBinds[KeyNameToCode(_S'c')]:= 'capture';
-DefaultBinds[KeyNameToCode(_S'r')]:= 'record';
-DefaultBinds[KeyNameToCode(_S'h')]:= 'findhh';
-DefaultBinds[KeyNameToCode(_S'p')]:= 'pause';
-DefaultBinds[KeyNameToCode(_S's')]:= '+speedup';
-DefaultBinds[KeyNameToCode(_S't')]:= 'chat';
-DefaultBinds[KeyNameToCode(_S'y')]:= 'confirm';
-
-DefaultBinds[KeyNameToCode('mousem')]:= 'zoomreset';
-DefaultBinds[KeyNameToCode('wheelup')]:= 'zoomin';
-DefaultBinds[KeyNameToCode('wheeldown')]:= 'zoomout';
-
-DefaultBinds[KeyNameToCode('f12')]:= 'fullscr';
+        InitDefaultBinds
+end;
 
 
-DefaultBinds[KeyNameToCode('mousel')]:= '/put';
-DefaultBinds[KeyNameToCode('mouser')]:= 'ammomenu';
-DefaultBinds[KeyNameToCode('backspace')]:= 'hjump';
-DefaultBinds[KeyNameToCode('tab')]:= 'switch';
-DefaultBinds[KeyNameToCode('return')]:= 'ljump';
-DefaultBinds[KeyNameToCode('space')]:= '+attack';
-DefaultBinds[KeyNameToCode('up')]:= '+up';
-DefaultBinds[KeyNameToCode('down')]:= '+down';
-DefaultBinds[KeyNameToCode('left')]:= '+left';
-DefaultBinds[KeyNameToCode('right')]:= '+right';
-DefaultBinds[KeyNameToCode('left_shift')]:= '+precise';
 
-
-DefaultBinds[KeyNameToCode('j0a0u')]:= '+left';
-DefaultBinds[KeyNameToCode('j0a0d')]:= '+right';
-DefaultBinds[KeyNameToCode('j0a1u')]:= '+up';
-DefaultBinds[KeyNameToCode('j0a1d')]:= '+down';
-for i:= 1 to 10 do DefaultBinds[KeyNameToCode('f'+IntToStr(i))]:= 'slot '+char(i+48);
-for i:= 1 to 5  do DefaultBinds[KeyNameToCode(IntToStr(i))]:= 'timer '+IntToStr(i);
-
-loadBinds('dbind', cPathz[ptConfig] + '/settings.ini');
-end;
-
+{$IFNDEF MOBILE}
 procedure SetBinds(var binds: TBinds);
-{$IFNDEF MOBILE}
 var
     t: LongInt;
-{$ENDIF}
 begin
-{$IFDEF MOBILE}
-    binds:= binds; // avoid hint
-    CurrentBinds:= DefaultBinds;
-{$ELSE}
     for t:= 0 to cKbdMaxIndex do
         if (CurrentBinds[t] <> binds[t]) and tkbd[t] then
             ProcessKey(t, False);
 
     CurrentBinds:= binds;
+end;
+{$ELSE}
+procedure SetBinds(var binds: TBinds);
+begin
+    binds:= binds; // avoid hint
+    CurrentBinds:= DefaultBinds;
+end;
 {$ENDIF}
-end;
 
 procedure SetDefaultBinds;
 begin
@@ -438,7 +462,7 @@
 var
     k: LongInt;
 begin
-    SDL_GetKeyState(@k);
+    SDL_GetKeyboardState(@k);
     k:= k + joy * (ControllerNumAxes[joy]*2 + ControllerNumHats[joy]*4 + ControllerNumButtons[joy]*2);
     ProcessKey(k +  axis*2, value > 20000);
     ProcessKey(k + (axis*2)+1, value < -20000);
@@ -448,7 +472,7 @@
 var
     k: LongInt;
 begin
-    SDL_GetKeyState(@k);
+    SDL_GetKeyboardState(@k);
     k:= k + joy * (ControllerNumAxes[joy]*2 + ControllerNumHats[joy]*4 + ControllerNumButtons[joy]*2);
     ProcessKey(k +  ControllerNumAxes[joy]*2 + hat*4 + 0, (value and SDL_HAT_UP)   <> 0);
     ProcessKey(k +  ControllerNumAxes[joy]*2 + hat*4 + 1, (value and SDL_HAT_RIGHT)<> 0);
@@ -460,7 +484,7 @@
 var
     k: LongInt;
 begin
-    SDL_GetKeyState(@k);
+    SDL_GetKeyboardState(@k);
     k:= k + joy * (ControllerNumAxes[joy]*2 + ControllerNumHats[joy]*4 + ControllerNumButtons[joy]*2);
     ProcessKey(k +  ControllerNumAxes[joy]*2 + ControllerNumHats[joy]*4 + button, pressed);
 end;
--- a/hedgewars/uLand.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uLand.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -263,7 +263,7 @@
 TryDo(Surface <> nil, 'Assert (LandSurface <> nil) failed', true);
 
 if SDL_MustLock(Surface) then
-    SDLTry(SDL_LockSurface(Surface) >= 0, true);
+    SDLTry(SDL_LockSurface(Surface) >= 0, 'SDL_LockSurface', true);
 
 p:= Surface^.pixels;
 for y:= 0 to LAND_HEIGHT - 1 do
@@ -451,7 +451,7 @@
     cpX:= (LAND_WIDTH - tmpsurf^.w) div 2;
     cpY:= LAND_HEIGHT - tmpsurf^.h;
     if SDL_MustLock(tmpsurf) then
-        SDLTry(SDL_LockSurface(tmpsurf) >= 0, true);
+        SDLTry(SDL_LockSurface(tmpsurf) >= 0, 'SDL_LockSurface', true);
 
         p:= tmpsurf^.pixels;
         for y:= 0 to Pred(tmpsurf^.h) do
--- a/hedgewars/uLandGenTemplateBased.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uLandGenTemplateBased.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -9,7 +9,7 @@
 var minDistance, dabDiv: LongInt; // different details size
 
 implementation
-uses uVariables, uConsts, uFloat, uLandUtils, uRandom, SDLh, math;
+uses uVariables, uTypes, uConsts, uFloat, uLandUtils, uRandom, SDLh, math;
 
 
 procedure SetPoints(var Template: TEdgeTemplate; var pa: TPixAr; fps: PPointArray);
@@ -327,6 +327,9 @@
         DivideEdges(Template.FillPointsCount, pa)
     until i = pa.Count;
 
+{$IFDEF IPHONEOS}
+    if GameType <> gmtLandPreview then
+{$ENDIF}
     // make it smooth
     BezierizeEdge(pa, _0_2);
 end;
--- a/hedgewars/uLandGraphics.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uLandGraphics.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -716,7 +716,7 @@
 col:= Frame div numFramesFirstCol;
 
 if SDL_MustLock(Image) then
-    SDLTry(SDL_LockSurface(Image) >= 0, true);
+    SDLTry(SDL_LockSurface(Image) >= 0, 'TryPlaceOnLand', true);
 
 bpp:= Image^.format^.BytesPerPixel;
 TryDo(bpp = 4, 'It should be 32 bpp sprite', true);
@@ -835,7 +835,7 @@
 col:= Frame div numFramesFirstCol;
 
 if SDL_MustLock(Image) then
-    SDLTry(SDL_LockSurface(Image) >= 0, true);
+    SDLTry(SDL_LockSurface(Image) >= 0, 'EraseLand', true);
 
 bpp:= Image^.format^.BytesPerPixel;
 TryDo(bpp = 4, 'It should be 32 bpp sprite', true);
@@ -918,7 +918,7 @@
 col:= Frame div numFramesFirstCol;
 
 if SDL_MustLock(Image) then
-    SDLTry(SDL_LockSurface(Image) >= 0, true);
+    SDLTry(SDL_LockSurface(Image) >= 0, 'SDL_LockSurface', true);
 
 bpp:= Image^.format^.BytesPerPixel;
 TryDo(bpp = 4, 'It should be 32 bpp sprite', true);
@@ -930,7 +930,7 @@
 TryDo(finalSurface <> nil, 'GetPlaceCollisionTex: fail to create surface', true);
 
 if SDL_MustLock(finalSurface) then
-    SDLTry(SDL_LockSurface(finalSurface) >= 0, true);
+    SDLTry(SDL_LockSurface(finalSurface) >= 0, 'GetPlaceCollisionTex', true);
 
 p:= PLongWordArray(@(PLongWordArray(Image^.pixels)^[ (Image^.pitch div 4) * row * h + col * w ]));
 pt:= PLongWordArray(finalSurface^.pixels);
--- a/hedgewars/uLandObjects.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uLandObjects.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -109,7 +109,7 @@
 WriteToConsole('Generating collision info... ');
 
 if SDL_MustLock(Image) then
-    SDLTry(SDL_LockSurface(Image) >= 0, true);
+    SDLTry(SDL_LockSurface(Image) >= 0, 'SDL_LockSurface', true);
 
 bpp:= Image^.format^.BytesPerPixel;
 TryDo(bpp = 4, 'Land object should be 32bit', true);
@@ -160,7 +160,7 @@
 WriteToConsole('Generating collision info... ');
 
 if SDL_MustLock(Image) then
-    SDLTry(SDL_LockSurface(Image) >= 0, true);
+    SDLTry(SDL_LockSurface(Image) >= 0, 'SDL_LockSurface', true);
 
 bpp:= Image^.format^.BytesPerPixel;
 TryDo(bpp = 4, 'Land object should be 32bit', true);
@@ -208,8 +208,8 @@
 
 procedure InitRects;
 begin
-RectCount:= 0;
-New(Rects)
+    RectCount:= 0;
+    New(Rects)
 end;
 
 procedure FreeRects;
@@ -365,7 +365,7 @@
 CheckCanPlace:= bRes;
 end;
 
-function TryPut(var Obj: TThemeObject): boolean; overload;
+function TryPut(var Obj: TThemeObject): boolean;
 const MaxPointsIndex = 2047;
 var x, y: Longword;
     ar: array[0..MaxPointsIndex] of TPoint;
@@ -386,12 +386,12 @@
                 begin
                 ar[cnt].x:= x;
                 ar[cnt].y:= y;
-                inc(cnt);
-                if cnt > MaxPointsIndex then // buffer is full, do not check the rest land
+                if cnt >= MaxPointsIndex then // buffer is full, do not check the rest land
                     begin
                     y:= LAND_HEIGHT;
                     x:= LAND_WIDTH;
                     end
+                    else inc(cnt);
                 end;
             inc(y, 3);
         until y >= LAND_HEIGHT - Height;
@@ -412,7 +412,7 @@
 TryPut:= bRes;
 end;
 
-function TryPut(var Obj: TSprayObject; Surface: PSDL_Surface): boolean; overload;
+function TryPut2(var Obj: TSprayObject; Surface: PSDL_Surface): boolean;
 const MaxPointsIndex = 8095;
 var x, y: Longword;
     ar: array[0..MaxPointsIndex] of TPoint;
@@ -420,7 +420,7 @@
     r: TSDL_Rect;
     bRes: boolean;
 begin
-TryPut:= false;
+TryPut2:= false;
 cnt:= 0;
 with Obj do
     begin
@@ -439,18 +439,19 @@
                 begin
                 ar[cnt].x:= x;
                 ar[cnt].y:= y;
-                inc(cnt);
-                if cnt > MaxPointsIndex then // buffer is full, do not check the rest land
+                if cnt >= MaxPointsIndex then // buffer is full, do not check the rest land
                     begin
-                    y:= 5000;
-                    x:= 5000;
+                    y:= $FF000000;
+                    x:= $FF000000;
                     end
+                    else inc(cnt);
                 end;
             inc(y, 12);
         until y >= LAND_HEIGHT - Height - 8;
         inc(x, getrandom(12) + 12)
     until x >= LAND_WIDTH - Width;
     bRes:= cnt <> 0;
+AddFileLog('CHECKPOINT 004');
     if bRes then
         begin
         i:= getrandom(cnt);
@@ -464,7 +465,7 @@
         end
     else Maxcnt:= 0
     end;
-TryPut:= bRes;
+TryPut2:= bRes;
 end;
 
 
@@ -845,13 +846,13 @@
         exit;
     WriteLnToConsole('Adding theme objects...');
 
-    for i:=0 to ThemeObjects.Count do
+    for i:=0 to Pred(ThemeObjects.Count) do
         ThemeObjects.objs[i].Maxcnt := max(1, (ThemeObjects.objs[i].Maxcnt * MaxHedgehogs) div 18); // Maxcnt is proportional to map size, but allow objects to span even if we're on a tiny map
 
     repeat
         t := getrandom(ThemeObjects.Count);
         b := false;
-        for i:=0 to ThemeObjects.Count do
+        for i:= 0 to Pred(ThemeObjects.Count) do
             begin
             ii := (i+t) mod ThemeObjects.Count;
 
@@ -869,18 +870,18 @@
         exit;
     WriteLnToConsole('Adding spray objects...');
 
-    for i:=0 to SprayObjects.Count do
+    for i:= 0 to Pred(SprayObjects.Count) do
         SprayObjects.objs[i].Maxcnt := max(1, (SprayObjects.objs[i].Maxcnt * MaxHedgehogs) div 18); // Maxcnt is proportional to map size, but allow objects to span even if we're on a tiny map
 
     repeat
         t := getrandom(SprayObjects.Count);
         b := false;
-        for i:=0 to SprayObjects.Count do
+        for i:= 0 to Pred(SprayObjects.Count) do
             begin
             ii := (i+t) mod SprayObjects.Count;
 
             if SprayObjects.objs[ii].Maxcnt <> 0 then
-                b := b or TryPut(SprayObjects.objs[ii], Surface)
+                b := b or TryPut2(SprayObjects.objs[ii], Surface)
             end;
     until not b;
 end;
@@ -915,7 +916,6 @@
 procedure AddOnLandObjects(Surface: PSDL_Surface);
 begin
 InitRects;
-//AddSprayObjects(Surface, SprayObjects, 12);
 AddSprayObjects(Surface, SprayObjects);
 FreeRects
 end;
--- a/hedgewars/uLocale.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uLocale.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -30,7 +30,7 @@
 function  GetEventString(e: TEventId): ansistring;
 
 {$IFDEF HWLIBRARY}
-procedure LoadLocaleWrapper(str: pchar); cdecl; export;
+procedure LoadLocaleWrapper(path: pchar; filename: pchar); cdecl; export;
 {$ENDIF}
 
 implementation
@@ -133,9 +133,20 @@
 end;
 
 {$IFDEF HWLIBRARY}
-procedure LoadLocaleWrapper(str: pchar); cdecl; export;
+procedure LoadLocaleWrapper(path: pchar; filename: pchar); cdecl; export;
 begin
-    LoadLocale(Strpas(str));
+// FIXME
+{    PathPrefix := Strpas(path);
+ 
+    uUtils.initModule(false);
+    uVariables.initModule;
+    uPhysFSLayer.initModule;
+} 
+    LoadLocale(Strpas(filename));
+{ 
+    uPhysFSLayer.freeModule;
+    uVariables.freeModule;
+    uUtils.freeModule;}
 end;
 {$ENDIF}
 
--- a/hedgewars/uMisc.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uMisc.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -30,11 +30,7 @@
 function  doSurfaceConversion(tmpsurf: PSDL_Surface): PSDL_Surface;
 function MakeScreenshot(filename: shortstring; k: LongInt; dump: LongWord): boolean;
 function  GetTeamStatString(p: PTeam): shortstring;
-{$IFDEF SDL2}
 function  SDL_RectMake(x, y, width, height: LongInt): TSDL_Rect; inline;
-{$ELSE}
-function  SDL_RectMake(x, y: SmallInt; width, height: Word): TSDL_Rect; inline;
-{$ENDIF}
 
 implementation
 uses SysUtils, uVariables, uUtils
@@ -304,7 +300,7 @@
 image^.size:= size;
 image^.buffer:= p;
 
-SDL_CreateThread(@SaveScreenshot{$IFDEF SDL2}, 'snapshot'{$ENDIF}, image);
+SDL_CreateThread(@SaveScreenshot, PChar('snapshot'), image);
 MakeScreenshot:= true; // possibly it is not true but we will not wait for thread to terminate
 end;
 
@@ -322,11 +318,7 @@
     end;
 end;
 
-{$IFDEF SDL2}
 function SDL_RectMake(x, y, width, height: LongInt): TSDL_Rect; inline;
-{$ELSE}
-function SDL_RectMake(x, y: SmallInt; width, height: Word): TSDL_Rect; inline;
-{$ENDIF}
 begin
     SDL_RectMake.x:= x;
     SDL_RectMake.y:= y;
@@ -341,32 +333,15 @@
     GetTeamStatString:= s;
 end;
 
-{$IFDEF SDL2}
-// FIXME - pretty sure this is not handling endianness correctly like the SDL1 is
+procedure initModule;
 const SDL_PIXELFORMAT_ABGR8888 = (1 shl 28) or (6 shl 24) or (7 shl 20) or (6 shl 16) or (32 shl 8) or 4;
-{$ELSE}
-const format: TSDL_PixelFormat = (
-        palette: nil; BitsPerPixel: 32; BytesPerPixel: 4;
-        Rloss: 0; Gloss: 0; Bloss: 0; Aloss: 0;
-        Rshift: RShift; Gshift: GShift; Bshift: BShift; Ashift: AShift;
-        RMask: RMask; GMask: GMask; BMask: BMask; AMask: AMask;
-        colorkey: 0; alpha: 255);
-{$ENDIF}
-
-procedure initModule;
 begin
-{$IFDEF SDL2}
     conversionFormat:= SDL_AllocFormat(SDL_PIXELFORMAT_ABGR8888);
-{$ELSE}
-    conversionFormat:= @format;
-{$ENDIF}
 end;
 
 procedure freeModule;
 begin
-{$IFDEF SDL2}
     SDL_FreeFormat(conversionFormat);
-{$ENDIF}
 end;
 
 end.
--- a/hedgewars/uPhysFSLayer.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uPhysFSLayer.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -171,7 +171,9 @@
 procedure initModule(localPrefix, userPrefix: PChar);
 var i: LongInt;
     cPhysfsId: shortstring;
+{$IFNDEF MOBILE}
     fp: PChar;
+{$ENDIF}
 begin
     //TODO: http://icculus.org/pipermail/physfs/2011-August/001006.html
     cPhysfsId:= GetCurrentDir() + {$IFDEF DARWIN}{$IFNDEF IPHONEOS}'/Hedgewars.app/Contents/MacOS/' + {$ENDIF}{$ENDIF} ' hedgewars';
@@ -179,6 +181,7 @@
     i:= PHYSFS_init(Str2PChar(cPhysfsId));
     //AddFileLog('[PhysFS] init: ' + inttostr(i));
 
+{$IFNDEF MOBILE}
     // mount system fonts paths first
     for i:= low(cFontsPaths) to high(cFontsPaths) do
         begin
@@ -186,6 +189,7 @@
             if fp <> nil then
                 pfsMount(ansistring(fp), PChar('/Fonts'));
         end;
+{$ENDIF}
 
     pfsMountAtRoot(localPrefix);
     pfsMountAtRoot(userPrefix + ansistring('/Data'));
--- a/hedgewars/uRender.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uRender.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -358,25 +358,29 @@
 {$ENDIF}
 
 function glLoadExtension(extension : shortstring) : boolean;
+var logmsg: shortstring;
 begin
-//TODO: pas2c does not handle {$IF (GLunit = gles11) OR DEFINED(PAS2C)}
-{$IFNDEF PAS2C}
-{$IF GLunit = gles11}
-    // FreePascal doesnt come with OpenGL ES 1.1 Extension headers
     extension:= extension; // avoid hint
     glLoadExtension:= false;
-    AddFileLog('OpenGL - "' + extension + '" skipped')
-{$ELSE}
+    logmsg:= 'OpenGL - "' + extension + '" skipped';
+
+{$IFNDEF IPHONEOS}
+//TODO: pas2c does not handle
+{$IFNDEF PAS2C}
+// FreePascal doesnt come with OpenGL ES 1.1 Extension headers
+{$IF GLunit <> gles11}
+
     glLoadExtension:= glext_LoadExtension(extension);
+
     if glLoadExtension then
-        AddFileLog('OpenGL - "' + extension + '" loaded')
+        logmsg:= 'OpenGL - "' + extension + '" loaded'
     else
-        AddFileLog('OpenGL - "' + extension + '" failed to load');
-{$ENDIF}
+        logmsg:= 'OpenGL - "' + extension + '" failed to load';
 
-{$ELSE} // pas2c part
-    glLoadExtension:= false;
+{$ENDIF}
 {$ENDIF}
+{$ENDIF}
+    AddFileLog(logmsg);
 end;
 
 {$IFDEF USE_S3D_RENDERING OR USE_VIDEO_RECORDING}
@@ -427,17 +431,6 @@
     tmpint: LongInt;
     tmpn: LongInt;
 begin
-{$IFDEF MOBILE}
-    // TODO: this function creates an opengles1.1 context
-    // un-comment below and add proper logic to support opengles2.0
-    //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
-    //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
-    if SDLGLcontext = nil then
-        SDLGLcontext:= SDL_GL_CreateContext(SDLwindow);
-    SDLTry(SDLGLcontext <> nil, true);
-    SDL_GL_SetSwapInterval(1);
-{$ENDIF}
-
     // suppress hint/warning
     AuxBufNum:= AuxBufNum;
 
--- a/hedgewars/uRenderUtils.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uRenderUtils.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -99,7 +99,7 @@
     tmpsurf:= TTF_RenderUTF8_Blended(Fontz[Font].Handle, PChar(s), clr);
     finalRect.x:= X + cFontBorder + 2;
     finalRect.y:= Y + cFontBorder;
-    SDLTry(tmpsurf <> nil, true);
+    SDLTry(tmpsurf <> nil, 'TTF_RenderUTF8_Blended', true);
     SDL_UpperBlit(tmpsurf, @textRect, Surface, @finalRect);
     SDL_FreeSurface(tmpsurf);
     finalRect.x:= X;
@@ -522,7 +522,7 @@
         rect.x:= edgeHeight + 1 + ((i - w) div 2);
         // trying to more evenly position the text, vertically
         rect.y:= edgeHeight + ((j-(numLines*h)) div 2) + line * h;
-        SDLTry(tmpsurf <> nil, true);
+        SDLTry(tmpsurf <> nil, 'TTF_Init', true);
         SDL_UpperBlit(tmpsurf, nil, finalSurface, @rect);
         SDL_FreeSurface(tmpsurf);
         inc(line);
--- a/hedgewars/uScript.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uScript.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -628,7 +628,9 @@
         begin
         gear := SpawnFakeCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2),
         HealthCrate, lua_toboolean(L, 3), lua_toboolean(L, 4));
-        lua_pushinteger(L, gear^.uid);
+        if gear <> nil then
+             lua_pushinteger(L, gear^.uid)
+        else lua_pushnil(L)
         end
     else
         lua_pushnil(L);
@@ -642,7 +644,9 @@
         begin
         gear := SpawnFakeCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2),
         AmmoCrate, lua_toboolean(L, 3), lua_toboolean(L, 4));
-        lua_pushinteger(L, gear^.uid);
+        if gear <> nil then
+             lua_pushinteger(L, gear^.uid)
+        else lua_pushnil(L)
         end
     else
         lua_pushnil(L);
@@ -656,7 +660,9 @@
         begin
         gear := SpawnFakeCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2),
         UtilityCrate, lua_toboolean(L, 3), lua_toboolean(L, 4));
-        lua_pushinteger(L, gear^.uid);
+        if gear <> nil then
+             lua_pushinteger(L, gear^.uid)
+        else lua_pushnil(L)
         end
     else
         lua_pushnil(L);
@@ -675,9 +681,8 @@
             health:= cHealthCaseAmount;
         gear := SpawnCustomCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), HealthCrate, health, 0);
         if gear <> nil then
-            lua_pushinteger(L, gear^.uid)
-        else
-            lua_pushnil(L);
+             lua_pushinteger(L, gear^.uid)
+        else lua_pushnil(L);
         end
     else
         lua_pushnil(L);
@@ -694,9 +699,8 @@
              gear := SpawnCustomCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), AmmoCrate, lua_tointeger(L, 3), 0)
         else gear := SpawnCustomCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), AmmoCrate, lua_tointeger(L, 3), lua_tointeger(L, 4));
         if gear <> nil then
-            lua_pushinteger(L, gear^.uid)
-        else
-            lua_pushnil(L);
+             lua_pushinteger(L, gear^.uid)
+        else lua_pushnil(L);
         end
     else
         lua_pushnil(L);
@@ -713,9 +717,8 @@
              gear := SpawnCustomCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), UtilityCrate, lua_tointeger(L, 3), 0)
         else gear := SpawnCustomCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), UtilityCrate, lua_tointeger(L, 3), lua_tointeger(L, 4));
         if gear <> nil then
-            lua_pushinteger(L, gear^.uid)
-        else
-            lua_pushnil(L);
+             lua_pushinteger(L, gear^.uid)
+        else lua_pushnil(L);
        end
     else
         lua_pushnil(L);
@@ -917,29 +920,30 @@
             lua_pushinteger(L, gear^.AdvBounce);
             lua_pushinteger(L, Integer(gear^.ImpactSound));
             lua_pushinteger(L, gear^.nImpactSounds);
-            lua_pushinteger(L, gear^.Tint)
+            lua_pushinteger(L, gear^.Tint);
+            lua_pushinteger(L, gear^.Damage)
             end
         else
             begin
             lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
             lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
-            lua_pushnil(L)
+            lua_pushnil(L); lua_pushnil(L)
             end
         end
     else
         begin
         lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
         lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
-        lua_pushnil(L)
+        lua_pushnil(L); lua_pushnil(L)
         end;
-    lc_getgearvalues:= 11
+    lc_getgearvalues:= 12
 end;
 
 function lc_setgearvalues(L : Plua_State) : LongInt; Cdecl;
 var gear : PGear;
 begin
-// Currently allows 1-12 params
-//    if CheckLuaParamCount(L, 12, 'SetGearValues', 'gearUid, Angle, Power, WDTimer, Radius, Density, Karma, DirAngle, AdvBounce, ImpactSound, # ImpactSounds, Tint') then
+// Currently allows 1-13 params
+//    if CheckLuaParamCount(L, 13, 'SetGearValues', 'gearUid, Angle, Power, WDTimer, Radius, Density, Karma, DirAngle, AdvBounce, ImpactSound, # ImpactSounds, Tint, Damage') then
 //        begin
         gear:= GearByUID(lua_tointeger(L, 1));
         if gear <> nil then
@@ -965,7 +969,9 @@
             if not lua_isnoneornil(L, 11) then
                 gear^.nImpactSounds := lua_tointeger(L, 11);
             if not lua_isnoneornil(L, 12) then
-                gear^.Tint := lua_tointeger(L, 12)
+                gear^.Tint := lua_tointeger(L, 12);
+            if not lua_isnoneornil(L, 13) then
+                gear^.Damage := lua_tointeger(L, 13);
             end;
 //        end
 //    else
@@ -2885,6 +2891,12 @@
 
 procedure GetGlobals;
 begin
+// TODO
+// Use setters instead, because globals should be read-only!
+// Otherwise globals might be changed by Lua, but then unexpectatly overwritten by engine when a ScriptCall is triggered by whatever Lua is doing!
+// Sure, one could work around that in engine (e.g. by setting writable globals in SetGlobals only when their engine-side value has actually changed since SetGlobals was called the last time...), but things just get messier and messier then.
+// It is inconsistent anyway to have some globals be read-only and others not with no indication whatsoever.
+// -- sheepluva
 TurnTimeLeft:= ScriptGetInteger('TurnTimeLeft');
 end;
 
--- a/hedgewars/uSound.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uSound.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -301,7 +301,7 @@
 end;
 
 procedure InitSound;
-const channels: LongInt = {$IFDEF MOBILE}1{$ELSE}2{$ENDIF};
+const channels: LongInt = 2;
 var success: boolean;
 begin
     if not (isSoundEnabled or isMusicEnabled) then
@@ -322,7 +322,7 @@
     end;
 
     WriteToConsole('Init SDL_mixer... ');
-    SDLTry(Mix_Init(MIX_INIT_OGG) <> 0, true);
+    SDLTry(Mix_Init(MIX_INIT_OGG) <> 0, 'Mix_Init', true);
     WriteLnToConsole(msgOK);
 
     Mix_AllocateChannels(Succ(chanTPU));
@@ -424,7 +424,7 @@
             s:= cPathz[Soundz[snd].Path] + '/' + Soundz[snd].FileName;
             WriteToConsole(msgLoading + s + ' ');
             defVoicepack^.chunks[snd]:= Mix_LoadWAV_RW(rwopsOpenRead(s), 1);
-            SDLTry(defVoicepack^.chunks[snd] <> nil, true);
+            SDLTry(defVoicepack^.chunks[snd] <> nil, 'Mix_LoadWAV_RW', true);
             WriteLnToConsole(msgOK);
             end;
         lastChan[snd]:= Mix_PlayChannelTimed(-1, defVoicepack^.chunks[snd], 0, -1)
@@ -523,7 +523,7 @@
             s:= cPathz[Soundz[snd].Path] + '/' + Soundz[snd].FileName;
             WriteToConsole(msgLoading + s + ' ');
             defVoicepack^.chunks[snd]:= Mix_LoadWAV_RW(rwopsOpenRead(s), 1);
-            SDLTry(defVoicepack^.chunks[snd] <> nil, true);
+            SDLTry(defVoicepack^.chunks[snd] <> nil, 'Mix_LoadWAV_RW', true);
             WriteLnToConsole(msgOK);
             end;
         if fadems > 0 then
@@ -574,10 +574,10 @@
     WriteToConsole(msgLoading + s + ' ');
 
     Mus:= Mix_LoadMUS_RW(rwopsOpenRead(s));
-    SDLTry(Mus <> nil, false);
+    SDLTry(Mus <> nil, 'Mix_LoadMUS_RW', false);
     WriteLnToConsole(msgOK);
 
-    SDLTry(Mix_FadeInMusic(Mus, -1, 3000) <> -1, false)
+    SDLTry(Mix_FadeInMusic(Mus, -1, 3000) <> -1, 'Mix_FadeInMusic', false)
 end;
 
 procedure SetVolume(vol: LongInt);
--- a/hedgewars/uStore.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uStore.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -55,25 +55,20 @@
 procedure InitOffscreenOpenGL;
 {$ENDIF}
 
-{$IFDEF SDL2}
 procedure WarpMouse(x, y: Word); inline;
-{$ENDIF}
 procedure SwapBuffers; {$IFDEF USE_VIDEO_RECORDING}cdecl{$ELSE}inline{$ENDIF};
 procedure SetSkyColor(r, g, b: real);
 
 implementation
 uses uMisc, uConsole, uVariables, uUtils, uTextures, uRender, uRenderUtils,
      uCommands, uPhysFSLayer, uDebug
-    {$IFDEF USE_CONTEXT_RESTORE}, uWorld{$ENDIF}
-    {$IF NOT DEFINED(SDL2) AND DEFINED(USE_VIDEO_RECORDING)}, glut {$ENDIF};
+    {$IFDEF USE_CONTEXT_RESTORE}, uWorld{$ENDIF};
 
-var
-{$IFDEF SDL2}
+//type TGPUVendor = (gvUnknown, gvNVIDIA, gvATI, gvIntel, gvApple);
+
+var 
     SDLwindow: PSDL_Window;
     SDLGLcontext: PSDL_GLContext;
-{$ELSE}
-    SDLPrimSurface: PSDL_Surface;
-{$ENDIF}
     squaresize : LongInt;
     numsquares : LongInt;
     ProgrTex: PTexture;
@@ -117,9 +112,9 @@
 clr.g:= (Color shr 8) and $FF;
 clr.b:= Color and $FF;
 tmpsurf:= TTF_RenderUTF8_Blended(Fontz[Font].Handle, s, clr);
-SDLTry(tmpsurf <> nil, true);
+SDLTry(tmpsurf <> nil, 'TTF_RenderUTF8_Blended', true);
 tmpsurf:= doSurfaceConversion(tmpsurf);
-SDLTry(tmpsurf <> nil, true);
+SDLTry(tmpsurf <> nil, 'TTF_RenderUTF8_Blended, doSurfaceConversion', true);
 SDL_UpperBlit(tmpsurf, nil, Surface, @finalRect);
 SDL_FreeSurface(tmpsurf);
 finalRect.x:= X;
@@ -361,7 +356,7 @@
             s:= cPathz[ptFonts] + '/' + Name;
             WriteToConsole(msgLoading + s + ' (' + inttostr(Height) + 'pt)... ');
             Handle:= TTF_OpenFontRW(rwopsOpenRead(s), true, Height);
-            SDLTry(Handle <> nil, true);
+            SDLTry(Handle <> nil, 'TTF_OpenFontRW', true);
             TTF_SetFontStyle(Handle, style);
             WriteLnToConsole(msgOK)
             end;
@@ -370,7 +365,11 @@
     begin
     MakeCrossHairs;
     LoadGraves;
+{$IFDEF IPHONEOS}
+    tmpHatSurf:= LoadDataImage(ptHats, 'chef', ifNone);
+{$ELSE}
     tmpHatSurf:= LoadDataImage(ptHats, 'Reserved/chef', ifNone);
+{$ENDIF}
     ChefHatTexture:= Surface2Tex(tmpHatSurf, true);
     freeTmpHatSurf();
     end;
@@ -606,7 +605,7 @@
             // anounce that loading failed
             OutError(msgFailed, false);
 
-            SDLTry(false, (imageFlags and ifCritical) <> 0);
+            SDLTry(false, 'LoadImage', (imageFlags and ifCritical) <> 0);
             // rwops was already freed by IMG_Load_RW
             rwops:= nil;
             end else
@@ -719,12 +718,12 @@
 {$IFDEF IPHONEOS}
     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0);
     SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 1);
+ 
+    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
+    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
 {$ELSE}
     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
 {$ENDIF}
-{$IFNDEF SDL2} // vsync is default in SDL2
-    SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, LongInt((cReducedQuality and rqDesyncVBlank) = 0));
-{$ENDIF}
     SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
     SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
     SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
@@ -737,38 +736,22 @@
 procedure SetupOpenGL;
 var buf: array[byte] of char;
 begin
+    AddFileLog('Setting up OpenGL (using driver: ' + shortstring(SDL_GetCurrentVideoDriver()) + ')');
 
-{$IFDEF SDL2}
-    AddFileLog('Setting up OpenGL (using driver: ' + shortstring(SDL_GetCurrentVideoDriver()) + ')');
-{$ELSE}
-    buf[0]:= char(0); // avoid compiler hint
-    AddFileLog('Setting up OpenGL (using driver: ' + shortstring(SDL_VideoDriverName(buf, sizeof(buf))) + ')');
-{$ENDIF}
+    // TODO: this function creates an opengles1.1 context
+    // un-comment below and add proper logic to support opengles2.0
+    //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
+    //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
+    if SDLGLcontext = nil then
+        SDLGLcontext:= SDL_GL_CreateContext(SDLwindow);
+    SDLTry(SDLGLcontext <> nil, 'SDLGLcontext', true);
+    SDLTry(SDL_GL_SetSwapInterval(1) = 0, 'SDL_GL_SetSwapInterval', true);
 
     RendererSetup();
+
+// gl2 init/matrix code was here, but removed
 end;
 
-(*
-procedure UpdateProjection;
-var
-    s: GLfloat;
-begin
-    s:=cScaleFactor;
-    mProjection[0,0]:= s/cScreenWidth; mProjection[0,1]:=  0.0;             mProjection[0,2]:=0.0; mProjection[0,3]:=  0.0;
-    mProjection[1,0]:= 0.0;            mProjection[1,1]:= -s/cScreenHeight; mProjection[1,2]:=0.0; mProjection[1,3]:=  0.0;
-    mProjection[2,0]:= 0.0;            mProjection[2,1]:=  0.0;             mProjection[2,2]:=1.0; mProjection[2,3]:=  0.0;
-    mProjection[3,0]:= cStereoDepth;   mProjection[3,1]:=  s/2;             mProjection[3,2]:=0.0; mProjection[3,3]:=  1.0;
-
-{$IFDEF GL2}
-    UpdateModelviewProjection;
-{$ELSE}
-    glMatrixMode(GL_PROJECTION);
-    glLoadMatrixf(@mProjection[0, 0]);
-    glMatrixMode(GL_MODELVIEW);
-{$ENDIF}
-end;
-*)
-
 ////////////////////////////////////////////////////////////////////////////////
 procedure AddProgress;
 var r: TSDL_Rect;
@@ -998,41 +981,23 @@
 end;
 
 {$IFDEF USE_VIDEO_RECORDING}
-{$IFDEF SDL2}
 procedure InitOffscreenOpenGL;
 begin
     // create hidden window
-    SDLwindow:= SDL_CreateWindow('hedgewars video rendering (SDL2 hidden window)',
+    SDLwindow:= SDL_CreateWindow(PChar('hedgewars video rendering (SDL2 hidden window)'),
                                  SDL_WINDOWPOS_CENTERED_MASK, SDL_WINDOWPOS_CENTERED_MASK,
                                  cScreenWidth, cScreenHeight,
                                  SDL_WINDOW_HIDDEN or SDL_WINDOW_OPENGL);
-    SDLTry(SDLwindow <> nil, true);
+    SDLTry(SDLwindow <> nil, 'SDL_CreateWindow', true);
     SetupOpenGL();
 end;
-{$ELSE}
-procedure InitOffscreenOpenGL;
-var ArgCount: LongInt;
-    PrgName: pchar;
-begin
-    ArgCount:= 1;
-    PrgName:= 'hwengine';
-    glutInit(@ArgCount, @PrgName);
-    glutInitWindowSize(cScreenWidth, cScreenHeight);
-    // we do not need a window, but without this call OpenGL will not initialize
-    glutCreateWindow('hedgewars video rendering (glut hidden window)');
-    glutHideWindow();
-    // we do not need to set this callback, but it is required for GLUT3 compat
-    glutDisplayFunc(@SwapBuffers);
-    RendererSetup();
-end;
-{$ENDIF} // SDL2
 {$ENDIF} // USE_VIDEO_RECORDING
 
 procedure chFullScr(var s: shortstring);
 var flags: Longword = 0;
     reinit: boolean = false;
     {$IFNDEF DARWIN}ico: PSDL_Surface;{$ENDIF}
-    {$IFDEF SDL2}x, y: LongInt;{$ENDIF}
+    x, y: LongInt;
 begin
     if cOnlyStats then
         begin
@@ -1055,28 +1020,12 @@
         end;
 
     AddFileLog('Preparing to change video parameters...');
-{$IFDEF SDL2}
     if SDLwindow = nil then
-{$ELSE}
-    if SDLPrimSurface = nil then
-{$ENDIF}
         begin
         // set window title
-    {$IFNDEF SDL2}
-        SDL_WM_SetCaption(_P'Hedgewars', nil);
-    {$ENDIF}
         WriteToConsole('Init SDL_image... ');
-        SDLTry(IMG_Init(IMG_INIT_PNG) <> 0, true);
+        SDLTry(IMG_Init(IMG_INIT_PNG) <> 0, 'IMG_Init', true);
         WriteLnToConsole(msgOK);
-        // load engine icon
-    {$IFNDEF DARWIN}
-        ico:= LoadDataImage(ptGraphics, 'hwengine', ifIgnoreCaps);
-        if ico <> nil then
-            begin
-            SDL_WM_SetIcon(ico, 0);
-            SDL_FreeSurface(ico)
-            end;
-    {$ENDIF}
         end
     else
         begin
@@ -1101,10 +1050,6 @@
         //uTextures.freeModule; //DEBUG ONLY
     {$ENDIF}
         AddFileLog('Freeing old primary surface...');
-    {$IFNDEF SDL2}
-        SDL_FreeSurface(SDLPrimSurface);
-        SDLPrimSurface:= nil;
-    {$ENDIF}
 {$ENDIF}
         end;
 
@@ -1118,7 +1063,6 @@
  *)
     SetupOpenGLAttributes();
 {$ENDIF}
-{$IFDEF SDL2}
     // these values in x and y make the window appear in the center
     x:= SDL_WINDOWPOS_CENTERED_MASK;
     y:= SDL_WINDOWPOS_CENTERED_MASK;
@@ -1137,26 +1081,18 @@
         flags:= flags or SDL_WINDOW_FULLSCREEN;
 
     if SDLwindow = nil then
-        SDLwindow:= SDL_CreateWindow('Hedgewars', x, y, cScreenWidth, cScreenHeight, flags);
-    SDLTry(SDLwindow <> nil, true);
-{$ELSE}
-    flags:= SDL_OPENGL or SDL_RESIZABLE;
-    if cFullScreen then
-        flags:= flags or SDL_FULLSCREEN;
-    if not cOnlyStats then
+        SDLwindow:= SDL_CreateWindow(PChar('Hedgewars'), x, y, cScreenWidth, cScreenHeight, flags);
+    SDLTry(SDLwindow <> nil, 'SDL_CreateWindow', true);
+
+    // load engine ico
+    {$IFNDEF DARWIN}
+    ico:= LoadDataImage(ptGraphics, 'hwengine', ifIgnoreCaps);
+    if ico <> nil then
         begin
-    {$IFDEF WIN32}
-        s:= SDL_getenv('SDL_VIDEO_CENTERED');
-        SDL_putenv('SDL_VIDEO_CENTERED=1');
+        SDL_SetWindowIcon(SDLwindow, ico);
+        SDL_FreeSurface(ico);
+        end;
     {$ENDIF}
-        SDLPrimSurface:= SDL_SetVideoMode(cScreenWidth, cScreenHeight, 0, flags);
-        SDLTry(SDLPrimSurface <> nil, true);
-    {$IFDEF WIN32}
-        SDL_putenv(str2pchar('SDL_VIDEO_CENTERED=' + s));
-    {$ENDIF}
-        end;
-{$ENDIF}
-
     SetupOpenGL();
 
     if reinit then
@@ -1179,7 +1115,6 @@
         end;
 end;
 
-{$IFDEF SDL2}
 // for sdl1.2 we directly call SDL_WarpMouse()
 // for sdl2 we provide a SDL_WarpMouse() which just calls this function
 // this has the advantage of reducing 'uses' and 'ifdef' statements
@@ -1188,17 +1123,12 @@
 begin
     SDL_WarpMouseInWindow(SDLwindow, x, y);
 end;
-{$ENDIF}
 
 procedure SwapBuffers; {$IFDEF USE_VIDEO_RECORDING}cdecl{$ELSE}inline{$ENDIF};
 begin
     if GameType = gmtRecord then
         exit;
-{$IFDEF SDL2}
     SDL_GL_SwapWindow(SDLwindow);
-{$ELSE}
-    SDL_GL_SwapBuffers();
-{$ENDIF}
 end;
 
 procedure SetSkyColor(r, g, b: real);
@@ -1226,12 +1156,8 @@
     // init all count texture pointers
     for i:= Low(CountTexz) to High(CountTexz) do
         CountTexz[i] := nil;
-{$IFDEF SDL2}
     SDLwindow:= nil;
     SDLGLcontext:= nil;
-{$ELSE}
-    SDLPrimSurface:= nil;
-{$ENDIF}
 
     prevHat:= 'NoHat';
     tmpHatSurf:= nil;
@@ -1253,10 +1179,8 @@
             end;
 
     TTF_Quit();
-{$IFDEF SDL2}
     SDL_GL_DeleteContext(SDLGLcontext);
     SDL_DestroyWindow(SDLwindow);
-{$ENDIF}
     SDL_Quit();
 end;
 end.
--- a/hedgewars/uTeams.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uTeams.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -604,7 +604,6 @@
     SplitBySpace(s, cs);
     SplitBySpace(cs, ts);
     Color:= StrToInt(cs);
-    TryDo(Color <> 0, 'Error: black team color', true);
 
     // color is always little endian so the mask must be constant also in big endian archs
     Color:= Color or $FF000000;
--- a/hedgewars/uTextures.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uTextures.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -236,7 +236,7 @@
 glBindTexture(GL_TEXTURE_2D, Surface2Tex^.id);
 
 if SDL_MustLock(surf) then
-    SDLTry(SDL_LockSurface(surf) >= 0, true);
+    SDLTry(SDL_LockSurface(surf) >= 0, 'Lock surface', true);
 
 fromP4:= Surf^.pixels;
 
--- a/hedgewars/uTouch.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uTouch.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -63,6 +63,7 @@
 
 const
     clickTime = 200;
+    nilFingerId = High(TSDL_FingerId);
     baseRectSize = 96;
 
 var
@@ -295,7 +296,7 @@
     end;
 
 if targetting then
-    AddCaption('Press the target button to mark the target', cWhiteColor, capgrpAmmoInfo);
+    AddCaption(trmsg[sidPressTarget], cWhiteColor, capgrpAmmoInfo);
 
 deleteFinger(pointerId);
 end;
--- a/hedgewars/uTypes.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uTypes.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -61,6 +61,7 @@
 {$IFDEF USE_TOUCH_INTERFACE}
             sprFireButton, sprArrowUp, sprArrowDown, sprArrowLeft, sprArrowRight,
             sprJumpWidget, sprAMWidget, sprPauseButton, sprTimerButton, sprTargetButton,
+            sprSwitchButton,
 {$ENDIF}
             sprFlake, sprHandRope, sprHandBazooka, sprHandShotgun,
             sprHandDEagle, sprHandAirAttack, sprHandBaseball, sprPHammer,
@@ -88,7 +89,7 @@
             sprBulletHit, sprSnowball, sprHandSnowball, sprSnow,
             sprSDFlake, sprSDWater, sprSDCloud, sprSDSplash, sprSDDroplet, sprTardis,
             sprSlider, sprBotlevels, sprHandKnife, sprKnife, sprStar, sprIceTexture, sprIceGun,
-            sprFrozenHog, sprAmRubber, sprBoing, sprCustom1, sprCustom2, sprAirMine
+            sprFrozenHog, sprAmRubber, sprBoing, sprCustom1, sprCustom2, sprAirMine, sprHandAirMine
             );
 
     // Gears that interact with other Gears and/or Land
@@ -455,7 +456,7 @@
             sidConfirm, sidSuddenDeath, sidRemaining, sidFuel, sidSync,
             sidNoEndTurn, sidNotYetAvailable, sidRoundSD, sidRoundsSD, sidReady,
             sidBounce1, sidBounce2, sidBounce3, sidBounce4, sidBounce5, sidBounce,
-            sidMute, sidAFK, sidAutoCameraOff, sidAutoCameraOn);
+            sidMute, sidAFK, sidAutoCameraOff, sidAutoCameraOn, sidPressTarget);
 
     // Events that are important for the course of the game or at least interesting for other reasons
     TEventId = (eidDied, eidDrowned, eidRoundStart, eidRoundWin, eidRoundDraw,
--- a/hedgewars/uVariables.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uVariables.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -21,7 +21,7 @@
 unit uVariables;
 interface
 
-uses SDLh, uTypes, uFloat, GLunit, uConsts, Math, uUtils, uMatrix;
+uses SDLh, uTypes, uFloat, GLunit, uConsts, Math, uUtils{$IFDEF GL2}, uMatrix{$ENDIF};
 
 var
 /////// init flags ///////
@@ -235,14 +235,12 @@
 
     LuaTemplateNumber : LongWord;
 
-    LastVoice : TVoice = ( snd: sndNone; voicepack: nil );
+    LastVoice : TVoice;
 
     mobileRecord: TMobileRecord;
 
     MaxTextureSize: LongInt;
 
-    ChatPasteBuffer: shortstring;
-
 /////////////////////////////////////
 //Buttons
 {$IFDEF USE_TOUCH_INTERFACE}
@@ -256,7 +254,10 @@
 
 var
     // these consts are here because they would cause circular dependencies in uConsts/uTypes
-    cPathz: array[TPathType] of shortstring = (
+    cPathz: array[TPathType] of shortstring;
+
+const
+    cPathzInit: array[TPathType] of shortstring = (
         '',                              // ptNone
         '/',                             // ptData
         '/Graphics',                     // ptGraphics
@@ -284,7 +285,10 @@
     );
 
 var
-    Fontz: array[THWFont] of THHFont = (
+    Fontz: array[THWFont] of THHFont;
+
+const
+    FontzInit: array[THWFont] of THHFont = (
             (Handle: nil;
             Height: 12;
             style: TTF_STYLE_NORMAL;
@@ -314,7 +318,10 @@
             );
 
 var
-    SpritesData: array[TSprite] of TSpriteData = (
+    SpritesData: array[TSprite] of TSpriteData;
+
+const
+    SpritesDataInit: array[TSprite] of TSpriteData = (
             (FileName:  'BlueWater'; Path: ptCurrTheme;AltPath: ptGraphics; Texture: nil; Surface: nil;
             Width:   0; Height:  0; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: true; getImageDimensions: true),// sprWater
             (FileName:     'Clouds'; Path: ptCurrTheme;AltPath: ptGraphics; Texture: nil; Surface: nil;
@@ -416,13 +423,13 @@
 {$IFDEF USE_TOUCH_INTERFACE}
             (FileName: 'firebutton'; Path: ptButtons; AltPath: ptNone; Texture: nil; Surface: nil;
             Width: 128; Height: 128; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHigh; getDimensions: false; getImageDimensions: true), // sprFireButton
-            (FileName: 'arrowUp'; Path: ptButtons; AltPath: ptNone; Texture: nil; Surface: nil;
+            (FileName: 'arrowup'; Path: ptButtons; AltPath: ptNone; Texture: nil; Surface: nil;
             Width: 100; Height: 100; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHigh; getDimensions: false; getImageDimensions: true), // sprArrowUp
-            (FileName: 'arrowDown'; Path: ptButtons; AltPath: ptNone; Texture: nil; Surface: nil;
+            (FileName: 'arrowdown'; Path: ptButtons; AltPath: ptNone; Texture: nil; Surface: nil;
             Width: 100; Height: 100; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHigh; getDimensions: false; getImageDimensions: true), // sprArrowDown
-            (FileName: 'arrowLeft'; Path: ptButtons; AltPath: ptNone; Texture: nil; Surface: nil;
+            (FileName: 'arrowleft'; Path: ptButtons; AltPath: ptNone; Texture: nil; Surface: nil;
             Width: 100; Height: 100; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHigh; getDimensions: false; getImageDimensions: true), // sprArrowLeft
-            (FileName: 'arrowRight'; Path: ptButtons; AltPath: ptNone; Texture: nil; Surface: nil;
+            (FileName: 'arrowright'; Path: ptButtons; AltPath: ptNone; Texture: nil; Surface: nil;
             Width: 100; Height: 100; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHigh; getDimensions: false; getImageDimensions: true), // sprArrowRight
             (FileName: 'forwardjump'; Path: ptButtons; AltPath: ptNone; Texture: nil; Surface: nil;
             Width: 128; Height: 128; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHigh; getDimensions: false; getImageDimensions: true), // sprAMWidget
@@ -430,10 +437,12 @@
             Width: 128; Height: 128; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHigh; getDimensions: false; getImageDimensions: true), // sprJumpWidget
             (FileName: 'pause'; Path: ptButtons; AltPath: ptNone; Texture: nil; Surface: nil;
             Width: 120; Height: 100; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHigh; getDimensions: false; getImageDimensions: true), // sprPauseButton
-            (FileName: 'pause'; Path: ptButtons; AltPath: ptNone; Texture: nil; Surface: nil;//TODO correct image
-            Width: 120; Height: 128; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHigh; getDimensions: false; getImageDimensions: true), // sprTimerButton
-            (FileName: 'forwardjump'; Path: ptButtons; AltPath: ptNone; Texture: nil; Surface: nil;//TODO correct image
-            Width: 120; Height: 128; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHigh; getDimensions: false; getImageDimensions: true), // sprTargetButton
+            (FileName: 'timerbutton'; Path: ptButtons; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width: 128; Height: 128; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHigh; getDimensions: false; getImageDimensions: true), // sprTimerButton
+            (FileName: 'targetbutton'; Path: ptButtons; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width: 128; Height: 128; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHigh; getDimensions: false; getImageDimensions: true), // sprTargetButton
+            (FileName: 'switchbutton'; Path: ptButtons; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width: 128; Height: 128; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHigh; getDimensions: false; getImageDimensions: true), // sprSwitchButton
 {$ENDIF}
             (FileName:      'Flake'; Path:ptCurrTheme; AltPath: ptNone; Texture: nil; Surface: nil;
             Width:  64; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHighest; getDimensions: false; getImageDimensions: true),// sprFlake
@@ -711,7 +720,9 @@
             (FileName:       'custom2'; Path: ptCurrTheme;AltPath: ptGraphics; Texture: nil; Surface: nil;
             Width:   0; Height:  0; imageWidth: 0; imageHeight: 0; saveSurf: true; priority: tpLow; getDimensions: true; getImageDimensions: true), // sprCustom2
             (FileName:      'AirMine'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
-            Width:  32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHighest; getDimensions: false; getImageDimensions: true)// sprAirMine
+            Width:  32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHighest; getDimensions: false; getImageDimensions: true), // sprAirMine
+            (FileName:  'amAirMine'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width:  64; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true) // sprHandAirMine
             );
 
 const
@@ -732,8 +743,8 @@
             (Sprite:   sprJuggle; FramesCount: 49; Interval:  38; cmd: '/juggle'; Voice: sndNone; VoiceDelay: 0)
             );
 
-var
-    Ammoz: array [TAmmoType] of record
+type
+    TAmmozRec = record
             NameId: TAmmoStrId;
             NameTex: PTexture;
             Probability, NumberInCase: Longword;
@@ -746,7 +757,13 @@
             PosCount: Longword;
             PosSprite: TSprite;
             ejectX, ejectY: Longint;
-            end = (
+            end;
+
+var
+    Ammoz: array [TAmmoType] of TAmmozRec;
+
+const
+    AmmozInit: array [TAmmoType] of TAmmozRec = (
             (NameId: sidNothing;
             NameTex: nil;
             Probability: 0;
@@ -1344,7 +1361,7 @@
             NameTex: nil;
             Probability: 100;
             NumberInCase: 4;
-            Ammo: (Propz: 0;
+            Ammo: (Propz: ammoprop_NeedUpDown;
                 Count: 4;
                 NumPerTurn: 0;
                 Timer: 0;
@@ -2135,6 +2152,7 @@
             NumberInCase: 1;
             Ammo: (Propz: ammoprop_Power or
                           ammoprop_AltUse or
+                          ammoprop_NeedUpDown or
                           ammoprop_NoRoundEnd;
                 Count: 2;
                 NumPerTurn: 0;
@@ -2216,6 +2234,7 @@
             Probability: 20;
             NumberInCase: 1;
             Ammo: (Propz: ammoprop_NoRoundEnd or
+                          ammoprop_NeedUpDown or
                           ammoprop_Utility;
                 Count: 1;
                 NumPerTurn: 0;
@@ -2488,7 +2507,19 @@
 
 procedure initModule;
 var s: shortstring;
+    i: integer;
 begin
+    // init LastVoice
+    LastVoice.snd:= sndNone;
+    LastVoice.voicepack:= nil;
+
+    // init arrays
+    Move(cPathzInit, cPathz, sizeof(cPathz));
+    Move(FontzInit, Fontz, sizeof(Fontz));
+    Move(SpritesDataInit, SpritesData, sizeof(SpritesData));
+    Move(AmmozInit, Ammoz, sizeof(Ammoz));
+
+
     cLocale:= cLocaleFName;
     SplitByChar(cLocale, s, '.');
 
@@ -2669,8 +2700,13 @@
     vobSDVelocity:= 15;
     vobSDFallSpeed:= 250;
 
+{$IFDEF MOBILE}
+    cMinScreenWidth  := min(cScreenWidth, 480);
+    cMinScreenHeight := min(cScreenHeight, 320);
+{$ELSE}
     cMinScreenWidth  := min(cScreenWidth, 640);
     cMinScreenHeight := min(cScreenHeight, 480);
+{$ENDIF}
 
     cNewScreenWidth    := cScreenWidth;
     cNewScreenHeight   := cScreenHeight;
@@ -2696,7 +2732,42 @@
     cViewLimitsDebug:= false;
     AprilOne := false;
 
-    ChatPasteBuffer:= '';
+    // initialize pointers to nil
+    // (don't rely on implicit init of fpc, because that one only happens ONCE when used as lib)
+    CurAmmoGear:= nil;
+    lastGearByUID:= nil;
+    GearsList:= nil;
+    CurrentTeam:= nil;
+    PreviousTeam:= nil;
+    CurrentHedgehog:= nil;
+    FollowGear:= nil;
+    lastVisualGearByUID:= nil;
+
+    ChefHatTexture:= nil;
+    CrosshairTexture:= nil;
+    GenericHealthTexture:= nil;
+    WeaponTooltipTex:= nil;
+    HHTexture:= nil;
+    LandBackSurface:= nil;
+    ConfirmTexture:= nil;
+    MissionIcons:= nil;
+    ropeIconTex:= nil;
+
+    for i:= Low(ClansArray) to High(ClansArray) do
+        begin
+        ClansArray[i]:= nil;
+        end;
+
+    for i:= Low(TeamsArray) to High(TeamsArray) do
+        begin
+        TeamsArray[i]:= nil;
+        end;
+
+    for i:= Low(CountTexz) to High(CountTexz) do
+        begin
+        CountTexz[i]:= nil;
+        end;
+
 end;
 
 procedure freeModule;
--- a/hedgewars/uWorld.pas	Tue Sep 08 19:20:58 2015 +0300
+++ b/hedgewars/uWorld.pas	Mon Nov 16 22:57:24 2015 +0300
@@ -1148,7 +1148,7 @@
 procedure ShiftWorld(Dir: LongInt); inline;
 begin
     preShiftWorldDx:= WorldDx;
-    WorldDx:= WorldDx + Dir * LongInt(playWidth);
+    WorldDx:= WorldDx + LongInt(Dir * LongInt(playWidth));
 
 end;
 
@@ -1737,7 +1737,7 @@
                     CursorPoint.X:= (prevPoint.X * 7 + dstX) div 8;
                 end;
 
-        if isPhone() or (cScreenHeight < 600) or ((FollowGear^.dY * z).Round < 10) then
+        if isPhone() or (cScreenHeight < 600) or (hwFloat(FollowGear^.dY * z).Round < 10) then
             CursorPoint.Y:= (prevPoint.Y * 7 + cScreenHeight - (hwRound(FollowGear^.Y) + WorldDy)) div 8
         else
             CursorPoint.Y:= (prevPoint.Y * 7 + cScreenHeight - (hwRound(FollowGear^.Y) + hwSign(FollowGear^.dY) * z + WorldDy)) div 8;
@@ -1930,7 +1930,7 @@
     ammoType:= CurrentHedgehog^.CurAmmoType;
 
 if(CurrentHedgehog <> nil)then
-    if (Ammoz[ammoType].Ammo.Propz and ammoprop_Timerable) <> 0 then
+    if ((Ammoz[ammoType].Ammo.Propz and ammoprop_Timerable) <> 0) and (ammoType <> amDrillStrike) then
         begin
         utilityWidget.sprite:= sprTimerButton;
         animateWidget(@utilityWidget, true, true);
@@ -1942,7 +1942,7 @@
         end
     else if ammoType = amSwitch then
         begin
-        utilityWidget.sprite:= sprTargetButton;
+        utilityWidget.sprite:= sprSwitchButton;
         animateWidget(@utilityWidget, true, true);
         end
     else if utilityWidget.show then
--- a/misc/liblua/Xcode/Lua.xcodeproj/project.pbxproj	Tue Sep 08 19:20:58 2015 +0300
+++ b/misc/liblua/Xcode/Lua.xcodeproj/project.pbxproj	Mon Nov 16 22:57:24 2015 +0300
@@ -3,7 +3,7 @@
 	archiveVersion = 1;
 	classes = {
 	};
-	objectVersion = 45;
+	objectVersion = 46;
 	objects = {
 
 /* Begin PBXBuildFile section */
@@ -289,8 +289,11 @@
 /* Begin PBXProject section */
 		0867D690FE84028FC02AAC07 /* Project object */ = {
 			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 0710;
+			};
 			buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "Lua" */;
-			compatibilityVersion = "Xcode 3.1";
+			compatibilityVersion = "Xcode 3.2";
 			developmentRegion = English;
 			hasScannedForEncodings = 1;
 			knownRegions = (
@@ -354,7 +357,6 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
 				COPY_PHASE_STRIP = NO;
 				DSTROOT = /tmp/Lua.dst;
 				GCC_DYNAMIC_NO_PIC = NO;
@@ -365,6 +367,8 @@
 				GCC_PREFIX_HEADER = Lua_Prefix.pch;
 				INSTALL_PATH = /usr/local/lib;
 				PRODUCT_NAME = Lua;
+				SKIP_INSTALL = YES;
+				VALID_ARCHS = "armv7 x86_64 arm64";
 			};
 			name = Debug;
 		};
@@ -372,49 +376,78 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
 				DSTROOT = /tmp/Lua.dst;
 				GCC_MODEL_TUNING = G5;
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
 				GCC_PREFIX_HEADER = Lua_Prefix.pch;
 				INSTALL_PATH = /usr/local/lib;
 				PRODUCT_NAME = Lua;
+				SKIP_INSTALL = YES;
+				VALID_ARCHS = "armv7 x86_64 arm64";
 			};
 			name = Release;
 		};
 		1DEB922308733DC00010E9CD /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
 				GCC_C_LANGUAGE_STANDARD = c99;
+				GCC_NO_COMMON_BLOCKS = YES;
 				GCC_OPTIMIZATION_LEVEL = 0;
 				GCC_THUMB_SUPPORT = NO;
 				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES;
+				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
-				IPHONEOS_DEPLOYMENT_TARGET = 3.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 7.0;
+				ONLY_ACTIVE_ARCH = YES;
 				OTHER_LDFLAGS = "-ObjC";
 				PREBINDING = NO;
 				SDKROOT = iphoneos;
 				TARGETED_DEVICE_FAMILY = "1,2";
+				VALID_ARCHS = "armv7 armv7s arm64";
 			};
 			name = Debug;
 		};
 		1DEB922408733DC00010E9CD /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				GCC_C_LANGUAGE_STANDARD = c99;
 				GCC_FAST_MATH = YES;
+				GCC_NO_COMMON_BLOCKS = YES;
 				GCC_THUMB_SUPPORT = NO;
 				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES;
+				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
-				IPHONEOS_DEPLOYMENT_TARGET = 3.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 7.0;
 				OTHER_LDFLAGS = "-ObjC";
 				PREBINDING = NO;
 				SDKROOT = iphoneos;
 				TARGETED_DEVICE_FAMILY = "1,2";
+				VALID_ARCHS = "armv7 armv7s arm64";
 			};
 			name = Release;
 		};
--- a/misc/libphysfs/CMakeLists.txt	Tue Sep 08 19:20:58 2015 +0300
+++ b/misc/libphysfs/CMakeLists.txt	Mon Nov 16 22:57:24 2015 +0300
@@ -148,7 +148,7 @@
 if(WINDOWS)
     set(PHYSFS_HAVE_CDROM_SUPPORT TRUE)
     set(PHYSFS_HAVE_THREAD_SUPPORT TRUE)
-    list(APPEND OTHER_LDFLAGS ${SDL_LIBRARY})
+    list(APPEND OTHER_LDFLAGS ${SDL2_LIBRARY})
 endif(WINDOWS)
 
 if(NOT PHYSFS_HAVE_CDROM_SUPPORT)
--- a/misc/libphysfs/Xcode/Physfs.xcodeproj/project.pbxproj	Tue Sep 08 19:20:58 2015 +0300
+++ b/misc/libphysfs/Xcode/Physfs.xcodeproj/project.pbxproj	Mon Nov 16 22:57:24 2015 +0300
@@ -3,7 +3,7 @@
 	archiveVersion = 1;
 	classes = {
 	};
-	objectVersion = 45;
+	objectVersion = 46;
 	objects = {
 
 /* Begin PBXBuildFile section */
@@ -178,8 +178,11 @@
 /* Begin PBXProject section */
 		0867D690FE84028FC02AAC07 /* Project object */ = {
 			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 0710;
+			};
 			buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "Physfs" */;
-			compatibilityVersion = "Xcode 3.1";
+			compatibilityVersion = "Xcode 3.2";
 			developmentRegion = English;
 			hasScannedForEncodings = 1;
 			knownRegions = (
@@ -230,7 +233,6 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
 				COPY_PHASE_STRIP = NO;
 				DSTROOT = /tmp/Physfs.dst;
 				GCC_DYNAMIC_NO_PIC = NO;
@@ -241,6 +243,7 @@
 				GCC_PREFIX_HEADER = Physfs_Prefix.pch;
 				INSTALL_PATH = /usr/local/lib;
 				PRODUCT_NAME = Physfs;
+				SKIP_INSTALL = YES;
 			};
 			name = Debug;
 		};
@@ -248,13 +251,13 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
 				DSTROOT = /tmp/Physfs.dst;
 				GCC_MODEL_TUNING = G5;
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
 				GCC_PREFIX_HEADER = Physfs_Prefix.pch;
 				INSTALL_PATH = /usr/local/lib;
 				PRODUCT_NAME = Physfs;
+				SKIP_INSTALL = YES;
 			};
 			name = Release;
 		};
@@ -262,20 +265,36 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
 				GCC_C_LANGUAGE_STANDARD = c99;
+				GCC_NO_COMMON_BLOCKS = YES;
 				GCC_OPTIMIZATION_LEVEL = 0;
 				GCC_PREPROCESSOR_DEFINITIONS = "";
 				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES;
+				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				HEADER_SEARCH_PATHS = (
 					"\"$(SRCROOT)/../../liblua\"",
 					"\"$(SRCROOT)/../../../../Library/SDL/include\"",
 				);
+				IPHONEOS_DEPLOYMENT_TARGET = 7.0;
+				ONLY_ACTIVE_ARCH = YES;
 				OTHER_LDFLAGS = "-ObjC";
 				PREBINDING = NO;
 				SDKROOT = iphoneos;
+				VALID_ARCHS = "armv7 x86_64 arm64";
 			};
 			name = Debug;
 		};
@@ -283,19 +302,33 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				GCC_C_LANGUAGE_STANDARD = c99;
+				GCC_NO_COMMON_BLOCKS = YES;
 				GCC_PREPROCESSOR_DEFINITIONS = "";
 				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES;
+				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				HEADER_SEARCH_PATHS = (
 					"\"$(SRCROOT)/../../liblua\"",
 					"\"$(SRCROOT)/../../../../Library/SDL/include\"",
 				);
+				IPHONEOS_DEPLOYMENT_TARGET = 7.0;
 				OTHER_LDFLAGS = "-ObjC";
 				PREBINDING = NO;
 				SDKROOT = iphoneos;
+				VALID_ARCHS = "armv7 x86_64 arm64";
 			};
 			name = Release;
 		};
--- a/misc/libphyslayer/CMakeLists.txt	Tue Sep 08 19:20:58 2015 +0300
+++ b/misc/libphyslayer/CMakeLists.txt	Mon Nov 16 22:57:24 2015 +0300
@@ -1,7 +1,7 @@
+find_package(SDL2 REQUIRED)
 
-find_package(SDL1or2)
+include_directories(${SDL2_INCLUDE_DIR})
 include_directories(${PHYSFS_INCLUDE_DIR})
-include_directories(${SDL_INCLUDE_DIR})
 include_directories(${LUA_INCLUDE_DIR})
 
 
@@ -15,7 +15,7 @@
 #compiles and links actual library
 add_library (physlayer ${PHYSLAYER_SRCS})
 #TODO: find good VERSION and SOVERSION values
-target_link_libraries(physlayer ${SDL_LIBRARY} lua physfs)
+target_link_libraries(physlayer ${SDL2_LIBRARY} lua physfs)
 install(TARGETS physlayer RUNTIME DESTINATION ${target_binary_install_dir}
                           LIBRARY DESTINATION ${target_library_install_dir}
                           ARCHIVE DESTINATION ${target_library_install_dir})
--- a/misc/libphyslayer/Xcode/Physlayer.xcodeproj/project.pbxproj	Tue Sep 08 19:20:58 2015 +0300
+++ b/misc/libphyslayer/Xcode/Physlayer.xcodeproj/project.pbxproj	Mon Nov 16 22:57:24 2015 +0300
@@ -3,7 +3,7 @@
 	archiveVersion = 1;
 	classes = {
 	};
-	objectVersion = 45;
+	objectVersion = 46;
 	objects = {
 
 /* Begin PBXBuildFile section */
@@ -124,8 +124,11 @@
 /* Begin PBXProject section */
 		0867D690FE84028FC02AAC07 /* Project object */ = {
 			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 0710;
+			};
 			buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "Physlayer" */;
-			compatibilityVersion = "Xcode 3.1";
+			compatibilityVersion = "Xcode 3.2";
 			developmentRegion = English;
 			hasScannedForEncodings = 1;
 			knownRegions = (
@@ -162,7 +165,6 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
 				COPY_PHASE_STRIP = NO;
 				DSTROOT = /tmp/Physlayer.dst;
 				GCC_DYNAMIC_NO_PIC = NO;
@@ -173,6 +175,7 @@
 				GCC_PREFIX_HEADER = Physlayer_Prefix.pch;
 				INSTALL_PATH = /usr/local/lib;
 				PRODUCT_NAME = Physlayer;
+				SKIP_INSTALL = YES;
 			};
 			name = Debug;
 		};
@@ -180,24 +183,70 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
 				DSTROOT = /tmp/Physlayer.dst;
 				GCC_MODEL_TUNING = G5;
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
 				GCC_PREFIX_HEADER = Physlayer_Prefix.pch;
 				INSTALL_PATH = /usr/local/lib;
 				PRODUCT_NAME = Physlayer;
+				SKIP_INSTALL = YES;
 			};
 			name = Release;
 		};
 		1DEB922308733DC00010E9CD /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
 				GCC_C_LANGUAGE_STANDARD = c99;
+				GCC_NO_COMMON_BLOCKS = YES;
 				GCC_OPTIMIZATION_LEVEL = 0;
 				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					"\"$(SRCROOT)/../../libphysfs\"",
+					"\"$(SRCROOT)/../../liblua\"",
+					"\"$(SRCROOT)/../../../../Library/SDL/include\"",
+				);
+				ONLY_ACTIVE_ARCH = YES;
+				OTHER_LDFLAGS = "-ObjC";
+				PREBINDING = NO;
+				SDKROOT = iphoneos;
+				VALID_ARCHS = "armv7 x86_64 arm64";
+			};
+			name = Debug;
+		};
+		1DEB922408733DC00010E9CD /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = c99;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES;
+				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				HEADER_SEARCH_PATHS = (
 					"\"$(SRCROOT)/../../libphysfs\"",
@@ -207,25 +256,7 @@
 				OTHER_LDFLAGS = "-ObjC";
 				PREBINDING = NO;
 				SDKROOT = iphoneos;
-			};
-			name = Debug;
-		};
-		1DEB922408733DC00010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
-				GCC_C_LANGUAGE_STANDARD = c99;
-				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = (
-					"\"$(SRCROOT)/../../libphysfs\"",
-					"\"$(SRCROOT)/../../liblua\"",
-					"\"$(SRCROOT)/../../../../Library/SDL/include\"",
-				);
-				OTHER_LDFLAGS = "-ObjC";
-				PREBINDING = NO;
-				SDKROOT = iphoneos;
+				VALID_ARCHS = "armv7 x86_64 arm64";
 			};
 			name = Release;
 		};
--- a/misc/winutils/include/GL/glut.h	Tue Sep 08 19:20:58 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,716 +0,0 @@
-#ifndef __glut_h__
-#define __glut_h__
-
-/* Copyright (c) Mark J. Kilgard, 1994, 1995, 1996, 1998. */
-
-/* This program is freely distributable without licensing fees  and is
-   provided without guarantee or warrantee expressed or  implied. This
-   program is -not- in the public domain. */
-
-#if defined(_WIN32)
-
-/* GLUT 3.7 now tries to avoid including <windows.h>
-   to avoid name space pollution, but Win32's <GL/gl.h>
-   needs APIENTRY and WINGDIAPI defined properly. */
-# if 0
-   /* This would put tons of macros and crap in our clean name space. */
-#  define  WIN32_LEAN_AND_MEAN
-#  include <windows.h>
-# else
-   /* XXX This is from Win32's <windef.h> */
-#  ifndef APIENTRY
-#   define GLUT_APIENTRY_DEFINED
-#   if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__) || defined(__LCC__)
-#    define APIENTRY    __stdcall
-#   else
-#    define APIENTRY
-#   endif
-#  endif
-   /* XXX This is from Win32's <winnt.h> */
-#  ifndef CALLBACK
-#   if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) || defined(__LCC__)
-#    define CALLBACK __stdcall
-#   else
-#    define CALLBACK
-#   endif
-#  endif
-   /* XXX Hack for lcc compiler.  It doesn't support __declspec(dllimport), just __stdcall. */
-#  if defined( __LCC__ )
-#   undef WINGDIAPI
-#   define WINGDIAPI __stdcall
-#  else
-   /* XXX This is from Win32's <wingdi.h> and <winnt.h> */
-#   ifndef WINGDIAPI
-#    define GLUT_WINGDIAPI_DEFINED
-#    define WINGDIAPI __declspec(dllimport)
-#   endif
-#  endif
-   /* XXX This is from Win32's <ctype.h> */
-#  ifndef _WCHAR_T_DEFINED
-typedef unsigned short wchar_t;
-#   define _WCHAR_T_DEFINED
-#  endif
-# endif
-
-/* To disable automatic library usage for GLUT, define GLUT_NO_LIB_PRAGMA
-   in your compile preprocessor options. */
-# if !defined(GLUT_BUILDING_LIB) && !defined(GLUT_NO_LIB_PRAGMA)
-#  pragma comment (lib, "winmm.lib")      /* link with Windows MultiMedia lib */
-/* To enable automatic SGI OpenGL for Windows library usage for GLUT,
-   define GLUT_USE_SGI_OPENGL in your compile preprocessor options.  */
-#  ifdef GLUT_USE_SGI_OPENGL
-#   pragma comment (lib, "opengl.lib")    /* link with SGI OpenGL for Windows lib */
-#   pragma comment (lib, "glu.lib")       /* link with SGI OpenGL Utility lib */
-#   pragma comment (lib, "glut.lib")      /* link with Win32 GLUT for SGI OpenGL lib */
-#  else
-#   pragma comment (lib, "opengl32.lib")  /* link with Microsoft OpenGL lib */
-#   pragma comment (lib, "glu32.lib")     /* link with Microsoft OpenGL Utility lib */
-#   pragma comment (lib, "glut32.lib")    /* link with Win32 GLUT lib */
-#  endif
-# endif
-
-/* To disable supression of annoying warnings about floats being promoted
-   to doubles, define GLUT_NO_WARNING_DISABLE in your compile preprocessor
-   options. */
-# ifndef GLUT_NO_WARNING_DISABLE
-#  pragma warning (disable:4244)  /* Disable bogus VC++ 4.2 conversion warnings. */
-#  pragma warning (disable:4305)  /* VC++ 5.0 version of above warning. */
-# endif
-
-/* Win32 has an annoying issue where there are multiple C run-time
-   libraries (CRTs).  If the executable is linked with a different CRT
-   from the GLUT DLL, the GLUT DLL will not share the same CRT static
-   data seen by the executable.  In particular, atexit callbacks registered
-   in the executable will not be called if GLUT calls its (different)
-   exit routine).  GLUT is typically built with the
-   "/MD" option (the CRT with multithreading DLL support), but the Visual
-   C++ linker default is "/ML" (the single threaded CRT).
-
-   One workaround to this issue is requiring users to always link with
-   the same CRT as GLUT is compiled with.  That requires users supply a
-   non-standard option.  GLUT 3.7 has its own built-in workaround where
-   the executable's "exit" function pointer is covertly passed to GLUT.
-   GLUT then calls the executable's exit function pointer to ensure that
-   any "atexit" calls registered by the application are called if GLUT
-   needs to exit.
-
-   Note that the __glut*WithExit routines should NEVER be called directly.
-   To avoid the atexit workaround, #define GLUT_DISABLE_ATEXIT_HACK. */
-
-/* XXX This is from Win32's <process.h> */
-# if !defined(_MSC_VER) && !defined(__cdecl)
-   /* Define __cdecl for non-Microsoft compilers. */
-#  define __cdecl
-#  define GLUT_DEFINED___CDECL
-# endif
-# ifndef _CRTIMP
-#  ifdef _NTSDK
-    /* Definition compatible with NT SDK */
-#   define _CRTIMP
-#  else
-    /* Current definition */
-#   ifdef _DLL
-#    define _CRTIMP __declspec(dllimport)
-#   else
-#    define _CRTIMP
-#   endif
-#  endif
-#  define GLUT_DEFINED__CRTIMP
-# endif
-
-/* GLUT API entry point declarations for Win32. */
-# ifdef GLUT_BUILDING_LIB
-#  define GLUTAPI __declspec(dllexport)
-# else
-#  ifdef _DLL
-#   define GLUTAPI __declspec(dllimport)
-#  else
-#   define GLUTAPI extern
-#  endif
-# endif
-
-/* GLUT callback calling convention for Win32. */
-# define GLUTCALLBACK __cdecl
-
-#endif  /* _WIN32 */
-
-#include <GL/gl.h>
-#include <GL/glu.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined(_WIN32)
-# ifndef GLUT_BUILDING_LIB
-extern _CRTIMP void __cdecl exit(int);
-# endif
-#else
-/* non-Win32 case. */
-/* Define APIENTRY and CALLBACK to nothing if we aren't on Win32. */
-# define APIENTRY
-# define GLUT_APIENTRY_DEFINED
-# define CALLBACK
-/* Define GLUTAPI and GLUTCALLBACK as below if we aren't on Win32. */
-# define GLUTAPI extern
-# define GLUTCALLBACK
-/* Prototype exit for the non-Win32 case (see above). */
-extern void exit(int);
-#endif
-
-/**
- GLUT API revision history:
-
- GLUT_API_VERSION is updated to reflect incompatible GLUT
- API changes (interface changes, semantic changes, deletions,
- or additions).
-
- GLUT_API_VERSION=1  First public release of GLUT.  11/29/94
-
- GLUT_API_VERSION=2  Added support for OpenGL/GLX multisampling,
- extension.  Supports new input devices like tablet, dial and button
- box, and Spaceball.  Easy to query OpenGL extensions.
-
- GLUT_API_VERSION=3  glutMenuStatus added.
-
- GLUT_API_VERSION=4  glutInitDisplayString, glutWarpPointer,
- glutBitmapLength, glutStrokeLength, glutWindowStatusFunc, dynamic
- video resize subAPI, glutPostWindowRedisplay, glutKeyboardUpFunc,
- glutSpecialUpFunc, glutIgnoreKeyRepeat, glutSetKeyRepeat,
- glutJoystickFunc, glutForceJoystickFunc (NOT FINALIZED!).
-**/
-#ifndef GLUT_API_VERSION  /* allow this to be overriden */
-#define GLUT_API_VERSION        3
-#endif
-
-/**
- GLUT implementation revision history:
-
- GLUT_XLIB_IMPLEMENTATION is updated to reflect both GLUT
- API revisions and implementation revisions (ie, bug fixes).
-
- GLUT_XLIB_IMPLEMENTATION=1  mjk's first public release of
- GLUT Xlib-based implementation.  11/29/94
-
- GLUT_XLIB_IMPLEMENTATION=2  mjk's second public release of
- GLUT Xlib-based implementation providing GLUT version 2
- interfaces.
-
- GLUT_XLIB_IMPLEMENTATION=3  mjk's GLUT 2.2 images. 4/17/95
-
- GLUT_XLIB_IMPLEMENTATION=4  mjk's GLUT 2.3 images. 6/?/95
-
- GLUT_XLIB_IMPLEMENTATION=5  mjk's GLUT 3.0 images. 10/?/95
-
- GLUT_XLIB_IMPLEMENTATION=7  mjk's GLUT 3.1+ with glutWarpPoitner.  7/24/96
-
- GLUT_XLIB_IMPLEMENTATION=8  mjk's GLUT 3.1+ with glutWarpPoitner
- and video resize.  1/3/97
-
- GLUT_XLIB_IMPLEMENTATION=9 mjk's GLUT 3.4 release with early GLUT 4 routines.
-
- GLUT_XLIB_IMPLEMENTATION=11 Mesa 2.5's GLUT 3.6 release.
-
- GLUT_XLIB_IMPLEMENTATION=12 mjk's GLUT 3.6 release with early GLUT 4 routines + signal handling.
-
- GLUT_XLIB_IMPLEMENTATION=13 mjk's GLUT 3.7 beta with GameGLUT support.
-
- GLUT_XLIB_IMPLEMENTATION=14 mjk's GLUT 3.7 beta with f90gl friend interface.
-
- GLUT_XLIB_IMPLEMENTATION=15 mjk's GLUT 3.7 beta sync'ed with Mesa <GL/glut.h>
-**/
-#ifndef GLUT_XLIB_IMPLEMENTATION  /* Allow this to be overriden. */
-#define GLUT_XLIB_IMPLEMENTATION    15
-#endif
-
-/* Display mode bit masks. */
-#define GLUT_RGB            0
-#define GLUT_RGBA           GLUT_RGB
-#define GLUT_INDEX          1
-#define GLUT_SINGLE         0
-#define GLUT_DOUBLE         2
-#define GLUT_ACCUM          4
-#define GLUT_ALPHA          8
-#define GLUT_DEPTH          16
-#define GLUT_STENCIL            32
-#if (GLUT_API_VERSION >= 2)
-#define GLUT_MULTISAMPLE        128
-#define GLUT_STEREO         256
-#endif
-#if (GLUT_API_VERSION >= 3)
-#define GLUT_LUMINANCE          512
-#endif
-
-/* Mouse buttons. */
-#define GLUT_LEFT_BUTTON        0
-#define GLUT_MIDDLE_BUTTON      1
-#define GLUT_RIGHT_BUTTON       2
-
-/* Mouse button  state. */
-#define GLUT_DOWN           0
-#define GLUT_UP             1
-
-#if (GLUT_API_VERSION >= 2)
-/* function keys */
-#define GLUT_KEY_F1         1
-#define GLUT_KEY_F2         2
-#define GLUT_KEY_F3         3
-#define GLUT_KEY_F4         4
-#define GLUT_KEY_F5         5
-#define GLUT_KEY_F6         6
-#define GLUT_KEY_F7         7
-#define GLUT_KEY_F8         8
-#define GLUT_KEY_F9         9
-#define GLUT_KEY_F10            10
-#define GLUT_KEY_F11            11
-#define GLUT_KEY_F12            12
-/* directional keys */
-#define GLUT_KEY_LEFT           100
-#define GLUT_KEY_UP         101
-#define GLUT_KEY_RIGHT          102
-#define GLUT_KEY_DOWN           103
-#define GLUT_KEY_PAGE_UP        104
-#define GLUT_KEY_PAGE_DOWN      105
-#define GLUT_KEY_HOME           106
-#define GLUT_KEY_END            107
-#define GLUT_KEY_INSERT         108
-#endif
-
-/* Entry/exit  state. */
-#define GLUT_LEFT           0
-#define GLUT_ENTERED            1
-
-/* Menu usage  state. */
-#define GLUT_MENU_NOT_IN_USE        0
-#define GLUT_MENU_IN_USE        1
-
-/* Visibility  state. */
-#define GLUT_NOT_VISIBLE        0
-#define GLUT_VISIBLE            1
-
-/* Window status  state. */
-#define GLUT_HIDDEN         0
-#define GLUT_FULLY_RETAINED     1
-#define GLUT_PARTIALLY_RETAINED     2
-#define GLUT_FULLY_COVERED      3
-
-/* Color index component selection values. */
-#define GLUT_RED            0
-#define GLUT_GREEN          1
-#define GLUT_BLUE           2
-
-#if defined(_WIN32)
-/* Stroke font constants (use these in GLUT program). */
-#define GLUT_STROKE_ROMAN       ((void*)0)
-#define GLUT_STROKE_MONO_ROMAN      ((void*)1)
-
-/* Bitmap font constants (use these in GLUT program). */
-#define GLUT_BITMAP_9_BY_15     ((void*)2)
-#define GLUT_BITMAP_8_BY_13     ((void*)3)
-#define GLUT_BITMAP_TIMES_ROMAN_10  ((void*)4)
-#define GLUT_BITMAP_TIMES_ROMAN_24  ((void*)5)
-#if (GLUT_API_VERSION >= 3)
-#define GLUT_BITMAP_HELVETICA_10    ((void*)6)
-#define GLUT_BITMAP_HELVETICA_12    ((void*)7)
-#define GLUT_BITMAP_HELVETICA_18    ((void*)8)
-#endif
-#else
-/* Stroke font opaque addresses (use constants instead in source code). */
-GLUTAPI void *glutStrokeRoman;
-GLUTAPI void *glutStrokeMonoRoman;
-
-/* Stroke font constants (use these in GLUT program). */
-#define GLUT_STROKE_ROMAN       (&glutStrokeRoman)
-#define GLUT_STROKE_MONO_ROMAN      (&glutStrokeMonoRoman)
-
-/* Bitmap font opaque addresses (use constants instead in source code). */
-GLUTAPI void *glutBitmap9By15;
-GLUTAPI void *glutBitmap8By13;
-GLUTAPI void *glutBitmapTimesRoman10;
-GLUTAPI void *glutBitmapTimesRoman24;
-GLUTAPI void *glutBitmapHelvetica10;
-GLUTAPI void *glutBitmapHelvetica12;
-GLUTAPI void *glutBitmapHelvetica18;
-
-/* Bitmap font constants (use these in GLUT program). */
-#define GLUT_BITMAP_9_BY_15     (&glutBitmap9By15)
-#define GLUT_BITMAP_8_BY_13     (&glutBitmap8By13)
-#define GLUT_BITMAP_TIMES_ROMAN_10  (&glutBitmapTimesRoman10)
-#define GLUT_BITMAP_TIMES_ROMAN_24  (&glutBitmapTimesRoman24)
-#if (GLUT_API_VERSION >= 3)
-#define GLUT_BITMAP_HELVETICA_10    (&glutBitmapHelvetica10)
-#define GLUT_BITMAP_HELVETICA_12    (&glutBitmapHelvetica12)
-#define GLUT_BITMAP_HELVETICA_18    (&glutBitmapHelvetica18)
-#endif
-#endif
-
-/* glutGet parameters. */
-#define GLUT_WINDOW_X           ((GLenum) 100)
-#define GLUT_WINDOW_Y           ((GLenum) 101)
-#define GLUT_WINDOW_WIDTH       ((GLenum) 102)
-#define GLUT_WINDOW_HEIGHT      ((GLenum) 103)
-#define GLUT_WINDOW_BUFFER_SIZE     ((GLenum) 104)
-#define GLUT_WINDOW_STENCIL_SIZE    ((GLenum) 105)
-#define GLUT_WINDOW_DEPTH_SIZE      ((GLenum) 106)
-#define GLUT_WINDOW_RED_SIZE        ((GLenum) 107)
-#define GLUT_WINDOW_GREEN_SIZE      ((GLenum) 108)
-#define GLUT_WINDOW_BLUE_SIZE       ((GLenum) 109)
-#define GLUT_WINDOW_ALPHA_SIZE      ((GLenum) 110)
-#define GLUT_WINDOW_ACCUM_RED_SIZE  ((GLenum) 111)
-#define GLUT_WINDOW_ACCUM_GREEN_SIZE    ((GLenum) 112)
-#define GLUT_WINDOW_ACCUM_BLUE_SIZE ((GLenum) 113)
-#define GLUT_WINDOW_ACCUM_ALPHA_SIZE    ((GLenum) 114)
-#define GLUT_WINDOW_DOUBLEBUFFER    ((GLenum) 115)
-#define GLUT_WINDOW_RGBA        ((GLenum) 116)
-#define GLUT_WINDOW_PARENT      ((GLenum) 117)
-#define GLUT_WINDOW_NUM_CHILDREN    ((GLenum) 118)
-#define GLUT_WINDOW_COLORMAP_SIZE   ((GLenum) 119)
-#if (GLUT_API_VERSION >= 2)
-#define GLUT_WINDOW_NUM_SAMPLES     ((GLenum) 120)
-#define GLUT_WINDOW_STEREO      ((GLenum) 121)
-#endif
-#if (GLUT_API_VERSION >= 3)
-#define GLUT_WINDOW_CURSOR      ((GLenum) 122)
-#endif
-#define GLUT_SCREEN_WIDTH       ((GLenum) 200)
-#define GLUT_SCREEN_HEIGHT      ((GLenum) 201)
-#define GLUT_SCREEN_WIDTH_MM        ((GLenum) 202)
-#define GLUT_SCREEN_HEIGHT_MM       ((GLenum) 203)
-#define GLUT_MENU_NUM_ITEMS     ((GLenum) 300)
-#define GLUT_DISPLAY_MODE_POSSIBLE  ((GLenum) 400)
-#define GLUT_INIT_WINDOW_X      ((GLenum) 500)
-#define GLUT_INIT_WINDOW_Y      ((GLenum) 501)
-#define GLUT_INIT_WINDOW_WIDTH      ((GLenum) 502)
-#define GLUT_INIT_WINDOW_HEIGHT     ((GLenum) 503)
-#define GLUT_INIT_DISPLAY_MODE      ((GLenum) 504)
-#if (GLUT_API_VERSION >= 2)
-#define GLUT_ELAPSED_TIME       ((GLenum) 700)
-#endif
-#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
-#define GLUT_WINDOW_FORMAT_ID       ((GLenum) 123)
-#endif
-
-#if (GLUT_API_VERSION >= 2)
-/* glutDeviceGet parameters. */
-#define GLUT_HAS_KEYBOARD       ((GLenum) 600)
-#define GLUT_HAS_MOUSE          ((GLenum) 601)
-#define GLUT_HAS_SPACEBALL      ((GLenum) 602)
-#define GLUT_HAS_DIAL_AND_BUTTON_BOX    ((GLenum) 603)
-#define GLUT_HAS_TABLET         ((GLenum) 604)
-#define GLUT_NUM_MOUSE_BUTTONS      ((GLenum) 605)
-#define GLUT_NUM_SPACEBALL_BUTTONS  ((GLenum) 606)
-#define GLUT_NUM_BUTTON_BOX_BUTTONS ((GLenum) 607)
-#define GLUT_NUM_DIALS          ((GLenum) 608)
-#define GLUT_NUM_TABLET_BUTTONS     ((GLenum) 609)
-#endif
-#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
-#define GLUT_DEVICE_IGNORE_KEY_REPEAT   ((GLenum) 610)
-#define GLUT_DEVICE_KEY_REPEAT          ((GLenum) 611)
-#define GLUT_HAS_JOYSTICK       ((GLenum) 612)
-#define GLUT_OWNS_JOYSTICK      ((GLenum) 613)
-#define GLUT_JOYSTICK_BUTTONS       ((GLenum) 614)
-#define GLUT_JOYSTICK_AXES      ((GLenum) 615)
-#define GLUT_JOYSTICK_POLL_RATE     ((GLenum) 616)
-#endif
-
-#if (GLUT_API_VERSION >= 3)
-/* glutLayerGet parameters. */
-#define GLUT_OVERLAY_POSSIBLE           ((GLenum) 800)
-#define GLUT_LAYER_IN_USE       ((GLenum) 801)
-#define GLUT_HAS_OVERLAY        ((GLenum) 802)
-#define GLUT_TRANSPARENT_INDEX      ((GLenum) 803)
-#define GLUT_NORMAL_DAMAGED     ((GLenum) 804)
-#define GLUT_OVERLAY_DAMAGED        ((GLenum) 805)
-
-#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
-/* glutVideoResizeGet parameters. */
-#define GLUT_VIDEO_RESIZE_POSSIBLE  ((GLenum) 900)
-#define GLUT_VIDEO_RESIZE_IN_USE    ((GLenum) 901)
-#define GLUT_VIDEO_RESIZE_X_DELTA   ((GLenum) 902)
-#define GLUT_VIDEO_RESIZE_Y_DELTA   ((GLenum) 903)
-#define GLUT_VIDEO_RESIZE_WIDTH_DELTA   ((GLenum) 904)
-#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA  ((GLenum) 905)
-#define GLUT_VIDEO_RESIZE_X     ((GLenum) 906)
-#define GLUT_VIDEO_RESIZE_Y     ((GLenum) 907)
-#define GLUT_VIDEO_RESIZE_WIDTH     ((GLenum) 908)
-#define GLUT_VIDEO_RESIZE_HEIGHT    ((GLenum) 909)
-#endif
-
-/* glutUseLayer parameters. */
-#define GLUT_NORMAL         ((GLenum) 0)
-#define GLUT_OVERLAY            ((GLenum) 1)
-
-/* glutGetModifiers return mask. */
-#define GLUT_ACTIVE_SHIFT               1
-#define GLUT_ACTIVE_CTRL                2
-#define GLUT_ACTIVE_ALT                 4
-
-/* glutSetCursor parameters. */
-/* Basic arrows. */
-#define GLUT_CURSOR_RIGHT_ARROW     0
-#define GLUT_CURSOR_LEFT_ARROW      1
-/* Symbolic cursor shapes. */
-#define GLUT_CURSOR_INFO        2
-#define GLUT_CURSOR_DESTROY     3
-#define GLUT_CURSOR_HELP        4
-#define GLUT_CURSOR_CYCLE       5
-#define GLUT_CURSOR_SPRAY       6
-#define GLUT_CURSOR_WAIT        7
-#define GLUT_CURSOR_TEXT        8
-#define GLUT_CURSOR_CROSSHAIR       9
-/* Directional cursors. */
-#define GLUT_CURSOR_UP_DOWN     10
-#define GLUT_CURSOR_LEFT_RIGHT      11
-/* Sizing cursors. */
-#define GLUT_CURSOR_TOP_SIDE        12
-#define GLUT_CURSOR_BOTTOM_SIDE     13
-#define GLUT_CURSOR_LEFT_SIDE       14
-#define GLUT_CURSOR_RIGHT_SIDE      15
-#define GLUT_CURSOR_TOP_LEFT_CORNER 16
-#define GLUT_CURSOR_TOP_RIGHT_CORNER    17
-#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 18
-#define GLUT_CURSOR_BOTTOM_LEFT_CORNER  19
-/* Inherit from parent window. */
-#define GLUT_CURSOR_INHERIT     100
-/* Blank cursor. */
-#define GLUT_CURSOR_NONE        101
-/* Fullscreen crosshair (if available). */
-#define GLUT_CURSOR_FULL_CROSSHAIR  102
-#endif
-
-/* GLUT initialization sub-API. */
-GLUTAPI void APIENTRY glutInit(int *argcp, char **argv);
-#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK)
-GLUTAPI void APIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int));
-#ifndef GLUT_BUILDING_LIB
-static void APIENTRY glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); }
-#define glutInit glutInit_ATEXIT_HACK
-#endif
-#endif
-GLUTAPI void APIENTRY glutInitDisplayMode(unsigned int mode);
-#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
-GLUTAPI void APIENTRY glutInitDisplayString(const char *string);
-#endif
-GLUTAPI void APIENTRY glutInitWindowPosition(int x, int y);
-GLUTAPI void APIENTRY glutInitWindowSize(int width, int height);
-GLUTAPI void APIENTRY glutMainLoop(void);
-
-/* GLUT window sub-API. */
-GLUTAPI int APIENTRY glutCreateWindow(const char *title);
-#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK)
-GLUTAPI int APIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int));
-#ifndef GLUT_BUILDING_LIB
-static int APIENTRY glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); }
-#define glutCreateWindow glutCreateWindow_ATEXIT_HACK
-#endif
-#endif
-GLUTAPI int APIENTRY glutCreateSubWindow(int win, int x, int y, int width, int height);
-GLUTAPI void APIENTRY glutDestroyWindow(int win);
-GLUTAPI void APIENTRY glutPostRedisplay(void);
-#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11)
-GLUTAPI void APIENTRY glutPostWindowRedisplay(int win);
-#endif
-GLUTAPI void APIENTRY glutSwapBuffers(void);
-GLUTAPI int APIENTRY glutGetWindow(void);
-GLUTAPI void APIENTRY glutSetWindow(int win);
-GLUTAPI void APIENTRY glutSetWindowTitle(const char *title);
-GLUTAPI void APIENTRY glutSetIconTitle(const char *title);
-GLUTAPI void APIENTRY glutPositionWindow(int x, int y);
-GLUTAPI void APIENTRY glutReshapeWindow(int width, int height);
-GLUTAPI void APIENTRY glutPopWindow(void);
-GLUTAPI void APIENTRY glutPushWindow(void);
-GLUTAPI void APIENTRY glutIconifyWindow(void);
-GLUTAPI void APIENTRY glutShowWindow(void);
-GLUTAPI void APIENTRY glutHideWindow(void);
-#if (GLUT_API_VERSION >= 3)
-GLUTAPI void APIENTRY glutFullScreen(void);
-GLUTAPI void APIENTRY glutSetCursor(int cursor);
-#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
-GLUTAPI void APIENTRY glutWarpPointer(int x, int y);
-#endif
-
-/* GLUT overlay sub-API. */
-GLUTAPI void APIENTRY glutEstablishOverlay(void);
-GLUTAPI void APIENTRY glutRemoveOverlay(void);
-GLUTAPI void APIENTRY glutUseLayer(GLenum layer);
-GLUTAPI void APIENTRY glutPostOverlayRedisplay(void);
-#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11)
-GLUTAPI void APIENTRY glutPostWindowOverlayRedisplay(int win);
-#endif
-GLUTAPI void APIENTRY glutShowOverlay(void);
-GLUTAPI void APIENTRY glutHideOverlay(void);
-#endif
-
-/* GLUT menu sub-API. */
-GLUTAPI int APIENTRY glutCreateMenu(void (GLUTCALLBACK *func)(int));
-#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK)
-GLUTAPI int APIENTRY __glutCreateMenuWithExit(void (GLUTCALLBACK *func)(int), void (__cdecl *exitfunc)(int));
-#ifndef GLUT_BUILDING_LIB
-static int APIENTRY glutCreateMenu_ATEXIT_HACK(void (GLUTCALLBACK *func)(int)) { return __glutCreateMenuWithExit(func, exit); }
-#define glutCreateMenu glutCreateMenu_ATEXIT_HACK
-#endif
-#endif
-GLUTAPI void APIENTRY glutDestroyMenu(int menu);
-GLUTAPI int APIENTRY glutGetMenu(void);
-GLUTAPI void APIENTRY glutSetMenu(int menu);
-GLUTAPI void APIENTRY glutAddMenuEntry(const char *label, int value);
-GLUTAPI void APIENTRY glutAddSubMenu(const char *label, int submenu);
-GLUTAPI void APIENTRY glutChangeToMenuEntry(int item, const char *label, int value);
-GLUTAPI void APIENTRY glutChangeToSubMenu(int item, const char *label, int submenu);
-GLUTAPI void APIENTRY glutRemoveMenuItem(int item);
-GLUTAPI void APIENTRY glutAttachMenu(int button);
-GLUTAPI void APIENTRY glutDetachMenu(int button);
-
-/* GLUT window callback sub-API. */
-GLUTAPI void APIENTRY glutDisplayFunc(void (GLUTCALLBACK *func)(void));
-GLUTAPI void APIENTRY glutReshapeFunc(void (GLUTCALLBACK *func)(int width, int height));
-GLUTAPI void APIENTRY glutKeyboardFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y));
-GLUTAPI void APIENTRY glutMouseFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y));
-GLUTAPI void APIENTRY glutMotionFunc(void (GLUTCALLBACK *func)(int x, int y));
-GLUTAPI void APIENTRY glutPassiveMotionFunc(void (GLUTCALLBACK *func)(int x, int y));
-GLUTAPI void APIENTRY glutEntryFunc(void (GLUTCALLBACK *func)(int state));
-GLUTAPI void APIENTRY glutVisibilityFunc(void (GLUTCALLBACK *func)(int state));
-GLUTAPI void APIENTRY glutIdleFunc(void (GLUTCALLBACK *func)(void));
-GLUTAPI void APIENTRY glutTimerFunc(unsigned int millis, void (GLUTCALLBACK *func)(int value), int value);
-GLUTAPI void APIENTRY glutMenuStateFunc(void (GLUTCALLBACK *func)(int state));
-#if (GLUT_API_VERSION >= 2)
-GLUTAPI void APIENTRY glutSpecialFunc(void (GLUTCALLBACK *func)(int key, int x, int y));
-GLUTAPI void APIENTRY glutSpaceballMotionFunc(void (GLUTCALLBACK *func)(int x, int y, int z));
-GLUTAPI void APIENTRY glutSpaceballRotateFunc(void (GLUTCALLBACK *func)(int x, int y, int z));
-GLUTAPI void APIENTRY glutSpaceballButtonFunc(void (GLUTCALLBACK *func)(int button, int state));
-GLUTAPI void APIENTRY glutButtonBoxFunc(void (GLUTCALLBACK *func)(int button, int state));
-GLUTAPI void APIENTRY glutDialsFunc(void (GLUTCALLBACK *func)(int dial, int value));
-GLUTAPI void APIENTRY glutTabletMotionFunc(void (GLUTCALLBACK *func)(int x, int y));
-GLUTAPI void APIENTRY glutTabletButtonFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y));
-#if (GLUT_API_VERSION >= 3)
-GLUTAPI void APIENTRY glutMenuStatusFunc(void (GLUTCALLBACK *func)(int status, int x, int y));
-GLUTAPI void APIENTRY glutOverlayDisplayFunc(void (GLUTCALLBACK *func)(void));
-#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
-GLUTAPI void APIENTRY glutWindowStatusFunc(void (GLUTCALLBACK *func)(int state));
-#endif
-#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
-GLUTAPI void APIENTRY glutKeyboardUpFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y));
-GLUTAPI void APIENTRY glutSpecialUpFunc(void (GLUTCALLBACK *func)(int key, int x, int y));
-GLUTAPI void APIENTRY glutJoystickFunc(void (GLUTCALLBACK *func)(unsigned int buttonMask, int x, int y, int z), int pollInterval);
-#endif
-#endif
-#endif
-
-/* GLUT color index sub-API. */
-GLUTAPI void APIENTRY glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue);
-GLUTAPI GLfloat APIENTRY glutGetColor(int ndx, int component);
-GLUTAPI void APIENTRY glutCopyColormap(int win);
-
-/* GLUT state retrieval sub-API. */
-GLUTAPI int APIENTRY glutGet(GLenum type);
-GLUTAPI int APIENTRY glutDeviceGet(GLenum type);
-#if (GLUT_API_VERSION >= 2)
-/* GLUT extension support sub-API */
-GLUTAPI int APIENTRY glutExtensionSupported(const char *name);
-#endif
-#if (GLUT_API_VERSION >= 3)
-GLUTAPI int APIENTRY glutGetModifiers(void);
-GLUTAPI int APIENTRY glutLayerGet(GLenum type);
-#endif
-
-/* GLUT font sub-API */
-GLUTAPI void APIENTRY glutBitmapCharacter(void *font, int character);
-GLUTAPI int APIENTRY glutBitmapWidth(void *font, int character);
-GLUTAPI void APIENTRY glutStrokeCharacter(void *font, int character);
-GLUTAPI int APIENTRY glutStrokeWidth(void *font, int character);
-#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
-GLUTAPI int APIENTRY glutBitmapLength(void *font, const unsigned char *string);
-GLUTAPI int APIENTRY glutStrokeLength(void *font, const unsigned char *string);
-#endif
-
-/* GLUT pre-built models sub-API */
-GLUTAPI void APIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks);
-GLUTAPI void APIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks);
-GLUTAPI void APIENTRY glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
-GLUTAPI void APIENTRY glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
-GLUTAPI void APIENTRY glutWireCube(GLdouble size);
-GLUTAPI void APIENTRY glutSolidCube(GLdouble size);
-GLUTAPI void APIENTRY glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
-GLUTAPI void APIENTRY glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
-GLUTAPI void APIENTRY glutWireDodecahedron(void);
-GLUTAPI void APIENTRY glutSolidDodecahedron(void);
-GLUTAPI void APIENTRY glutWireTeapot(GLdouble size);
-GLUTAPI void APIENTRY glutSolidTeapot(GLdouble size);
-GLUTAPI void APIENTRY glutWireOctahedron(void);
-GLUTAPI void APIENTRY glutSolidOctahedron(void);
-GLUTAPI void APIENTRY glutWireTetrahedron(void);
-GLUTAPI void APIENTRY glutSolidTetrahedron(void);
-GLUTAPI void APIENTRY glutWireIcosahedron(void);
-GLUTAPI void APIENTRY glutSolidIcosahedron(void);
-
-#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
-/* GLUT video resize sub-API. */
-GLUTAPI int APIENTRY glutVideoResizeGet(GLenum param);
-GLUTAPI void APIENTRY glutSetupVideoResizing(void);
-GLUTAPI void APIENTRY glutStopVideoResizing(void);
-GLUTAPI void APIENTRY glutVideoResize(int x, int y, int width, int height);
-GLUTAPI void APIENTRY glutVideoPan(int x, int y, int width, int height);
-
-/* GLUT debugging sub-API. */
-GLUTAPI void APIENTRY glutReportErrors(void);
-#endif
-
-#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
-/* GLUT device control sub-API. */
-/* glutSetKeyRepeat modes. */
-#define GLUT_KEY_REPEAT_OFF     0
-#define GLUT_KEY_REPEAT_ON      1
-#define GLUT_KEY_REPEAT_DEFAULT     2
-
-/* Joystick button masks. */
-#define GLUT_JOYSTICK_BUTTON_A      1
-#define GLUT_JOYSTICK_BUTTON_B      2
-#define GLUT_JOYSTICK_BUTTON_C      4
-#define GLUT_JOYSTICK_BUTTON_D      8
-
-GLUTAPI void APIENTRY glutIgnoreKeyRepeat(int ignore);
-GLUTAPI void APIENTRY glutSetKeyRepeat(int repeatMode);
-GLUTAPI void APIENTRY glutForceJoystickFunc(void);
-
-/* GLUT game mode sub-API. */
-/* glutGameModeGet. */
-#define GLUT_GAME_MODE_ACTIVE           ((GLenum) 0)
-#define GLUT_GAME_MODE_POSSIBLE         ((GLenum) 1)
-#define GLUT_GAME_MODE_WIDTH            ((GLenum) 2)
-#define GLUT_GAME_MODE_HEIGHT           ((GLenum) 3)
-#define GLUT_GAME_MODE_PIXEL_DEPTH      ((GLenum) 4)
-#define GLUT_GAME_MODE_REFRESH_RATE     ((GLenum) 5)
-#define GLUT_GAME_MODE_DISPLAY_CHANGED  ((GLenum) 6)
-
-GLUTAPI void APIENTRY glutGameModeString(const char *string);
-GLUTAPI int APIENTRY glutEnterGameMode(void);
-GLUTAPI void APIENTRY glutLeaveGameMode(void);
-GLUTAPI int APIENTRY glutGameModeGet(GLenum mode);
-#endif
-
-#ifdef __cplusplus
-}
-
-#endif
-
-#ifdef GLUT_APIENTRY_DEFINED
-# undef GLUT_APIENTRY_DEFINED
-# undef APIENTRY
-#endif
-
-#ifdef GLUT_WINGDIAPI_DEFINED
-# undef GLUT_WINGDIAPI_DEFINED
-# undef WINGDIAPI
-#endif
-
-#ifdef GLUT_DEFINED___CDECL
-# undef GLUT_DEFINED___CDECL
-# undef __cdecl
-#endif
-
-#ifdef GLUT_DEFINED__CRTIMP
-# undef GLUT_DEFINED__CRTIMP
-# undef _CRTIMP
-#endif
-
-#endif                  /* __glut_h__ */
Binary file project_files/Android-build/SDL-android-project/assets/Data/Graphics/Buttons/switchbutton.png has changed
Binary file project_files/Android-build/SDL-android-project/assets/Data/Graphics/Buttons/targetbutton.png has changed
Binary file project_files/Android-build/SDL-android-project/assets/Data/Graphics/Buttons/timerbutton.png has changed
--- a/project_files/HedgewarsMobile/Classes/AboutViewController.m	Tue Sep 08 19:20:58 2015 +0300
+++ b/project_files/HedgewarsMobile/Classes/AboutViewController.m	Mon Nov 16 22:57:24 2015 +0300
@@ -27,7 +27,10 @@
     return rotationManager(interfaceOrientation);
 }
 
--(void) viewDidLoad {
+-(void) viewDidLoad
+{
+    [super viewDidLoad];
+    
     [self.tableView setBackgroundColorForAnyTable:[UIColor clearColor]];
     self.tableView.allowsSelection = NO;
 
@@ -48,12 +51,23 @@
     [self.view insertSubview:background atIndex:0];
     [background release];
 
-    [super viewDidLoad];
+    [self localizeSegmentedControl];
 }
 
 -(IBAction) buttonPressed:(id) sender {
     [[AudioManagerController mainManager] playBackSound];
-    [[self parentViewController] dismissModalViewControllerAnimated:YES];
+    [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
+}
+
+#pragma mark - Segmented Control
+
+- (void)localizeSegmentedControl
+{
+    for (NSUInteger i = 0; i < self.segmentedControl.numberOfSegments; i++)
+    {
+        NSString *oldTitle = [self.segmentedControl titleForSegmentAtIndex:i];
+        [self.segmentedControl setTitle:NSLocalizedStringFromTable(oldTitle, @"About", nil) forSegmentAtIndex:i];
+    }
 }
 
 -(IBAction) segmentedControlChanged:(id) sender {
@@ -83,7 +97,8 @@
     cell.textLabel.text = [[self.people objectAtIndex:self.segmentedControl.selectedSegmentIndex] objectAtIndex:[indexPath row]];
     cell.textLabel.adjustsFontSizeToFitWidth = YES;
     cell.textLabel.minimumFontSize = 8;
-    cell.detailTextLabel.text = [[self.people objectAtIndex:(self.segmentedControl.selectedSegmentIndex + 5)] objectAtIndex:[indexPath row]];
+    NSString *detailsKey = [[self.people objectAtIndex:(self.segmentedControl.selectedSegmentIndex + 5)] objectAtIndex:[indexPath row]];
+    cell.detailTextLabel.text = NSLocalizedStringFromTable(detailsKey, @"About", nil);
 
     return cell;
 }
@@ -118,6 +133,7 @@
     label.textColor = [UIColor lightGrayColor];
     label.numberOfLines = 5;
     label.text = footerString;
+    [footerString release];
 
     label.backgroundColor = [UIColor clearColor];
     [footer addSubview:label];
--- a/project_files/HedgewarsMobile/Classes/Appirater.h	Tue Sep 08 19:20:58 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/*
- This file is part of Appirater, http://arashpayan.com
-
- Copyright (c) 2010, Arash Payan
- All rights reserved.
-
- 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.
- */
-
-
-#import <Foundation/Foundation.h>
-
-extern NSString *const kAppiraterLaunchDate;
-extern NSString *const kAppiraterLaunchCount;
-extern NSString *const kAppiraterCurrentVersion;
-extern NSString *const kAppiraterRatedCurrentVersion;
-extern NSString *const kAppiraterDeclinedToRate;
-
-/*
- Place your Apple generated software id here.
- */
-#define APPIRATER_APP_ID                391234866
-
-/*
- Your app's name.
- */
-#define APPIRATER_APP_NAME              [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]
-
-/*
- This is the message your users will see once they've passed the day+launches
- threshold.
- */
-#define APPIRATER_MESSAGE               [NSString stringWithFormat:@"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!", APPIRATER_APP_NAME]
-
-/*
- This is the title of the message alert that users will see.
- */
-#define APPIRATER_MESSAGE_TITLE         [NSString stringWithFormat:@"Rate %@", APPIRATER_APP_NAME]
-
-/*
- The text of the button that rejects reviewing the app.
- */
-#define APPIRATER_CANCEL_BUTTON         NSLocalizedString(@"No thanks",@"")
-
-/*
- Text of button that will send user to app review page.
- */
-#define APPIRATER_RATE_BUTTON           [NSString stringWithFormat:@"Rate %@", APPIRATER_APP_NAME]
-
-/*
- Text for button to remind the user to review later.
- */
-#define APPIRATER_RATE_LATER            NSLocalizedString(@"Remind me later",@"")
-
-/*
- Users will need to have the same version of your app installed for this many
- days before they will be prompted to rate it.
- */
-#define DAYS_UNTIL_PROMPT               3       // double
-
-/*
- Users will need to launch the same version of the app this many times before
- they will be prompted to rate it.
- */
-#define LAUNCHES_UNTIL_PROMPT           5      // integer
-
-/*
- 'YES' will show the Appirater alert everytime. Useful for testing how your message
- looks and making sure the link to your app's review page works.
- */
-#define APPIRATER_DEBUG                 NO      // bool
-
-@interface Appirater : NSObject <UIAlertViewDelegate> {
-
-}
-
-+(void) appLaunched;
-
-@end
--- a/project_files/HedgewarsMobile/Classes/Appirater.m	Tue Sep 08 19:20:58 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,159 +0,0 @@
-/*
- This file is part of Appirater, http://arashpayan.com
-
- Copyright (c) 2010, Arash Payan
- All rights reserved.
-
- 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.
- */
-
-
-#import "Appirater.h"
-#import <SystemConfiguration/SCNetworkReachability.h>
-#import <netinet/in.h>
-
-NSString *const kAppiraterLaunchDate            = @"kAppiraterLaunchDate";
-NSString *const kAppiraterLaunchCount           = @"kAppiraterLaunchCount";
-NSString *const kAppiraterCurrentVersion        = @"kAppiraterCurrentVersion";
-NSString *const kAppiraterRatedCurrentVersion   = @"kAppiraterRatedCurrentVersion";
-NSString *const kAppiraterDeclinedToRate        = @"kAppiraterDeclinedToRate";
-
-NSString *templateReviewURL = @"itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?id=APP_ID&onlyLatestVersion=true&pageNumber=0&sortOrdering=1&type=Purple+Software";
-
-@implementation Appirater
-
-+(void) appLaunched {
-    Appirater *appirater = [[Appirater alloc] init];
-    [NSThread detachNewThreadSelector:@selector(appLaunchedHandler) toTarget:appirater withObject:nil];
-}
-
--(void) appLaunchedHandler {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
-    if (APPIRATER_DEBUG) {
-        [self performSelectorOnMainThread:@selector(showPrompt) withObject:nil waitUntilDone:NO];
-        return;
-    }
-
-    BOOL willShowPrompt = NO;
-
-    // get the app's version
-    NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleVersionKey];
-
-    // get the version number that we've been tracking
-    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
-    NSString *trackingVersion = [userDefaults stringForKey:kAppiraterCurrentVersion];
-    if (trackingVersion == nil) {
-        trackingVersion = version;
-        [userDefaults setObject:version forKey:kAppiraterCurrentVersion];
-    }
-
-    if (APPIRATER_DEBUG)
-        DLog(@"APPIRATER Tracking version: %@", trackingVersion);
-
-    if ([trackingVersion isEqualToString:version]) {
-        // get the launch date
-        NSTimeInterval timeInterval = [userDefaults doubleForKey:kAppiraterLaunchDate];
-        if (timeInterval == 0) {
-            timeInterval = [[NSDate date] timeIntervalSince1970];
-            [userDefaults setDouble:timeInterval forKey:kAppiraterLaunchDate];
-        }
-
-        NSTimeInterval secondsSinceLaunch = [[NSDate date] timeIntervalSinceDate:[NSDate dateWithTimeIntervalSince1970:timeInterval]];
-        double secondsUntilPrompt = 60 * 60 * 24 * DAYS_UNTIL_PROMPT;
-
-        // get the launch count
-        int launchCount = [userDefaults integerForKey:kAppiraterLaunchCount];
-        launchCount++;
-        [userDefaults setInteger:launchCount forKey:kAppiraterLaunchCount];
-        if (APPIRATER_DEBUG)
-            NSLog(@"APPIRATER Launch count: %d", launchCount);
-
-        // have they previously declined to rate this version of the app?
-        BOOL declinedToRate = [userDefaults boolForKey:kAppiraterDeclinedToRate];
-
-        // have they already rated the app?
-        BOOL ratedApp = [userDefaults boolForKey:kAppiraterRatedCurrentVersion];
-
-        if (secondsSinceLaunch > secondsUntilPrompt &&
-             launchCount > LAUNCHES_UNTIL_PROMPT &&
-             !declinedToRate &&
-             !ratedApp) {
-            if ([HWUtils isNetworkReachable]) { // check if they can reach the app store
-                willShowPrompt = YES;
-                [self performSelectorOnMainThread:@selector(showPrompt) withObject:nil waitUntilDone:NO];
-            }
-        }
-    } else {
-        // it's a new version of the app, so restart tracking
-        [userDefaults setObject:version forKey:kAppiraterCurrentVersion];
-        [userDefaults setDouble:[[NSDate date] timeIntervalSince1970] forKey:kAppiraterLaunchDate];
-        [userDefaults setInteger:1 forKey:kAppiraterLaunchCount];
-        [userDefaults setBool:NO forKey:kAppiraterRatedCurrentVersion];
-        [userDefaults setBool:NO forKey:kAppiraterDeclinedToRate];
-    }
-
-    [userDefaults synchronize];
-    if (!willShowPrompt)
-        [self autorelease];
-
-    [pool release];
-}
-
--(void) showPrompt {
-    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:APPIRATER_MESSAGE_TITLE
-                                                        message:APPIRATER_MESSAGE
-                                                       delegate:self
-                                              cancelButtonTitle:APPIRATER_CANCEL_BUTTON
-                                              otherButtonTitles:APPIRATER_RATE_BUTTON, APPIRATER_RATE_LATER, nil];
-    [alertView show];
-    [alertView release];
-}
-
--(void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger) buttonIndex {
-    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
-
-    switch (buttonIndex) {
-        case 0:
-            // they don't want to rate it
-            [userDefaults setBool:YES forKey:kAppiraterDeclinedToRate];
-            break;
-        case 1:
-            // they want to rate it
-            [[UIApplication sharedApplication] openURL:
-             [NSURL URLWithString:[templateReviewURL stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%d", APPIRATER_APP_ID]]]];
-
-            [userDefaults setBool:YES forKey:kAppiraterRatedCurrentVersion];
-            break;
-        case 2:
-            // remind them later
-            break;
-        default:
-            break;
-    }
-
-    [userDefaults synchronize];
-
-    [self release];
-}
-
-@end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/ar.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "إذا كنت تستمع باستخدام %@، فهل تمانع بأن تأخذ دقيقة من وقتك لتقيمه؟ لن يستغرق الأمر أكثر من دقيقة. شكرا لدعمك!";
+"Rate %@" = "قيم %@";
+"No, Thanks" = "لا شكرا";
+"Remind me later" = "ذكرني لاحقا";
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/ca.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Si li agrada utilitzar %@, li importaria prendre’s un moment per a valorar-lo? No trigarà més d’un minut. Gràcies por la seva col·laboració!";
+"Rate %@" = "Valorar %@";
+"No, Thanks" = "No, gràcies";
+"Remind me later" = "Recordar-m’ho més tard";
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/cs.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Pokud se Vám aplikace %@ líbí, mohli byste ji prosím ohodnotit v App Store? Zabere to jen chvilku. Díky za Vaši podporu!";
+"Rate %@" = "Ohodnotit %@";
+"No, Thanks" = "Ne, díky";
+"Remind me later" = "Možná později";
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/da.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Hvis du synes om at bruge %@, vil du have noget imod at bruge et kort øjeblik på at bedømme det? Det tager kun et minut. Tak for din støtte!";
+"Rate %@" = "Bedøm %@";
+"No, Thanks" = "Nej tak";
+"Remind me later" = "Påmind mig senere";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/de.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Sie nutzen %@ gerne? Dann nehmen Sie sich bitte für eine Bewertung einen Moment Zeit! Es dauert nicht länger als eine Minute. Vielen Dank!";
+"Rate %@" = "Bewerte %@";
+"No, Thanks" = "Nein, danke";
+"Remind me later" = "Später erinnern";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/el.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Αν σου αρέσει το %@, θα μπορούσες να αφιερώσεις μια στιγμή για να το βαθμολογήσεις; Η διαδικασία είναι πολύ σύντομη. Ευχαριστούμε για τη στήριξη!";
+"Rate %@" = "Βαθμολόγηση του %@";
+"No, Thanks" = "Όχι, ευχαριστώ";
+"Remind me later" = "Υπενθύμιση αργότερα";
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/en.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!";
+"Rate %@" = "Rate %@";
+"No, Thanks" = "No, thanks";
+"Remind me later" = "Remind me later";
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/es.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Si te ha gustado  %@, ¿te gustaría calificarnos? No te tomará más de un minuto. ¡Gracias por tu colaboración!";
+"Rate %@" = "Calificar %@";
+"No, Thanks" = "No, gracias";
+"Remind me later" = "Recuérdame más tarde";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/fi.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Jos käytät mielelläsi %@, voisitko käyttää hetken ja arvostella sen? Se ei kestä minuuttia kauempaa. Kiitos tuestasi!";
+"Rate %@" = "Arvioi %@";
+"No, Thanks" = "Ei kiitos";
+"Remind me later" = "Muistuta minua myöhemmin";
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/fr.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Si vous aimez %@, voulez-vous prendre un moment pour l'évaluer ? Cela ne vous prendra pas plus d'une minute. Merci de votre soutien !";
+"Rate %@" = "Évaluer %@";
+"No, Thanks" = "Non, merci";
+"Remind me later" = "Me rappeler plus tard";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/he.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "אם נהנת להשתמש ב %@, האם תסכים לדרג אותה? זה לא יקח יותר מדקה. תודה על התמיכה!";
+"Rate %@" = "דרג את %@";
+"No, Thanks" = "לא תודה";
+"Remind me later" = "מאוחר יותר";
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/hu.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Ha tetszik a %@, ne felejtsd el értékelni az App Store-ban! Csak egy perc az egész. Köszönet a támogatásért!";
+"Rate %@" = "%@ értékelése";
+"No, Thanks" = "Most inkább nem";
+"Remind me later" = "Emlékeztess később";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/id.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Jika anda menyukai %@, maukah anda memberikan rating kepada aplikasi ini? Rating hanya memakan waktu kurang dari 1 menit. Terimakasih untuk dukungan anda!";
+"Rate %@" = "Rating %@";
+"No, Thanks" = "Tidak, terimakasih";
+"Remind me later" = "Silakan ingatkan saya lagi";
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/it.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Se ti piace %@, perché non dedichi qualche istante a darne una valutazione sull'App Store? Non richiederà più di un minuto. Grazie per il supporto!";
+"Rate %@" = "Valuta %@";
+"No, Thanks" = "No, grazie";
+"Remind me later" = "Ricordamelo più tardi";
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/ja.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "%@をお使いいただきありがとうございます。もしよろしければ、ほんの少しだけお時間をいただき評価をお願いできませんか?ご協力感謝いたします!";
+"Rate %@" = "%@を評価する";
+"No, Thanks" ="結構です";
+"Remind me later" = "あとで";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/ko.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "%@ 사용이 맘에 드셨나요? 잠시만 시간을 내서 평가를 부탁드리겠습니다. 감사합니다!";
+"Rate %@" = "%@ 평가하기";
+"No, Thanks" = "평가하지 않겠습니다";
+"Remind me later" = "다음에 평가하겠습니다";
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/ms.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Jika anda suka %@, bolehkah luangkan sedikit masa untuk beri penarafan? Tak sampai seminit pun. Terima kasih atas sokongan anda!";
+"Rate %@" = "Tarafkan %@";
+"No, Thanks" = "Terima kasih saja";
+"Remind me later" = "Ingatkan saya lain kali";
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/nb.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Hvis du liker å bruke %@, kan du ta deg et øyeblikk for å vurdere den? Det vil ikke ta mer enn ett minutt. Takk for din støtte!";
+"Rate %@" = "Vurder %@";
+"No, Thanks" = "Nei, takk";
+"Remind me later" = "Påminn meg senere";
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/nl.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Als het gebruik van %@ je bevalt, zou je dan een momentje de tijd willen nemen om het te beoordelen? Het duurt nog geen minuut. Bedankt voor je steun!";
+"Rate %@" = "%@ beoordelen";
+"No, Thanks" = "Nee, bedankt";
+"Remind me later" = "Herinner me er later aan";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/pl.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Jeżeli podoba Ci się korzystanie z %@, może zechciałbyś poświęcić chwilę czasu, aby ocenić aplikację? Nie zajmie Ci to więcej niż minutę. Dziękujemy za pomoc!";
+"Rate %@" = "Oceń %@";
+"No, Thanks" = "Nie, dziękuję";
+"Remind me later" = "Przypomnij później";
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/pt-BR.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Se você gosta de usar o %@, que tal avaliá-lo? Não levará mais de um minuto. Agradecemos o seu apoio!";
+"Rate %@" = "Avaliar o %@";
+"No, Thanks" = "Não, obrigado";
+"Remind me later" = "Mais tarde";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/pt.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Se você gosta de usar o %@, que tal avaliá-lo? Não levará mais de um minuto. Agradecemos o seu apoio!";
+"Rate %@" = "Avaliar o %@";
+"No, Thanks" = "Não, obrigado";
+"Remind me later" = "Mais tarde";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/ro.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Dacă îți place %@, acordă-i o notă te rog, nu durează mult. Mulțumim pentru susținere!";
+"Rate %@" = "Acordă notă pentru %@";
+"No, Thanks" = "Nu, mulțumesc";
+"Remind me later" = "Adu-mi aminte mai târziu";
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/ru.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Если Вам нравится %@, пожалуйста, поставьте свою оценку. Это займет у Вас не больше одной минуты.\n Спасибо за поддержку!";
+"Rate %@" = "Оценить %@";
+"No, Thanks" = "Нет, спасибо";
+"Remind me later" = "Напомнить позже";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/sk.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Pokiaľ sa Vám páči aplikácia %@, mohli by ste ju prosím ohodnotiť v App Store? Zaberie to len chvíľu. Vďaka za Vašu podporu!";
+"Rate %@" = "Ohodnotiť %@";
+"No, Thanks" = "Nie, ďakujem";
+"Remind me later" = "Pripomenúť neskôr";
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/sv.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Om du gillar att använda %@, kan du tänka dig att betygsätta det åt oss? Det tar bara en minut. Tack för hjälpen!";
+"Rate %@" = "Betygsätt %@";
+"No, Thanks" = "Nej tack";
+"Remind me later" = "Påminn mig senare";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/th.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "ถ้าคุณกำลังใช้ %@ โปรดสละเวลาสักครู่ในการให้อันดับแก่เรา คุณจะเสียเวลาไม่เกินหนึ่งนาที ขอบคุณสำหรับการสนับสนุน!";
+"Rate %@" = "ให้อันดับ %@";
+"No, Thanks" = "ไม่ ขอบคุณ";
+"Remind me later" = "เตือนฉันภายหลัง";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/tr.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Eğer %@ uygulamasını kullanmaktan keyif alıyorsanız, onu değerlendirmek için zaman ayırabilir misiniz? Desteğiniz için teşekkür ederiz!";
+"Rate %@" = "%@ uygulamasını değerlendir";
+"No, Thanks" = "Hayır, teşekkürler";
+"Remind me later" = "Daha sonra hatırlat";
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/uk.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Якщо вам сподобалося %@, будь ласка, поставте свою оцінку. Це займає не більше однієї хвилини.\n Дякуємо за підтримку!";
+"Rate %@" = "Оцінити %@";
+"No, Thanks" = "Ні, дякую";
+"Remind me later" = "Нагадати пізніше";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/vi.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Cảm ơn bạn đã sử dụng ứng dụng %@ trong thời gian qua, bạn có thể dành chút thời gian để đánh giá ứng dụng trong AppStore không?";
+"Rate %@" = "Đánh giá %@";
+"No, Thanks" = "Không, xin cảm ơn";
+"Remind me later" = "Hãy nhắc nhở tôi sau";
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/zh-Hans.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "如果你喜欢使用%@,你介意花一点时间给它评分吗?不会超过一分钟。感谢您的支持!";
+"Rate %@" = "给%@评分";
+"No, Thanks" = "不,谢谢";
+"Remind me later" = "稍后提醒我";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.bundle/zh-Hant.lproj/AppiraterLocalizable.strings	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,4 @@
+"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "如果你喜歡使用%@,你介意花一點時間給它評分嗎?不會超過一分鐘。感謝您的支持!";
+"Rate %@" = "給%@評分";
+"No, Thanks" = "不,謝謝";
+"Remind me later" = "稍後提醒我";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.h	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,331 @@
+/*
+ This file is part of Appirater.
+ 
+ Copyright (c) 2012, Arash Payan
+ All rights reserved.
+ 
+ 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.
+ */
+/*
+ * Appirater.h
+ * appirater
+ *
+ * Created by Arash Payan on 9/5/09.
+ * http://arashpayan.com
+ * Copyright 2012 Arash Payan. All rights reserved.
+ */
+
+#import <Foundation/Foundation.h>
+#import "AppiraterDelegate.h"
+#import <StoreKit/StoreKit.h>
+
+extern NSString *const kAppiraterFirstUseDate;
+extern NSString *const kAppiraterUseCount;
+extern NSString *const kAppiraterSignificantEventCount;
+extern NSString *const kAppiraterCurrentVersion;
+extern NSString *const kAppiraterRatedCurrentVersion;
+extern NSString *const kAppiraterDeclinedToRate;
+extern NSString *const kAppiraterReminderRequestDate;
+
+/*!
+ Your localized app's name.
+ */
+#define APPIRATER_LOCALIZED_APP_NAME    [[[NSBundle mainBundle] localizedInfoDictionary] objectForKey:@"CFBundleDisplayName"]
+
+/*!
+ Your app's name.
+ */
+#define APPIRATER_APP_NAME				APPIRATER_LOCALIZED_APP_NAME ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]
+
+/*!
+ This is the message your users will see once they've passed the day+launches
+ threshold.
+ */
+#define APPIRATER_LOCALIZED_MESSAGE     NSLocalizedStringFromTableInBundle(@"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!", @"AppiraterLocalizable", [Appirater bundle], nil)
+#define APPIRATER_MESSAGE				[NSString stringWithFormat:APPIRATER_LOCALIZED_MESSAGE, APPIRATER_APP_NAME]
+
+/*!
+ This is the title of the message alert that users will see.
+ */
+#define APPIRATER_LOCALIZED_MESSAGE_TITLE   NSLocalizedStringFromTableInBundle(@"Rate %@", @"AppiraterLocalizable", [Appirater bundle], nil)
+#define APPIRATER_MESSAGE_TITLE             [NSString stringWithFormat:APPIRATER_LOCALIZED_MESSAGE_TITLE, APPIRATER_APP_NAME]
+
+/*!
+ The text of the button that rejects reviewing the app.
+ */
+#define APPIRATER_CANCEL_BUTTON			NSLocalizedStringFromTableInBundle(@"No, Thanks", @"AppiraterLocalizable", [Appirater bundle], nil)
+
+/*!
+ Text of button that will send user to app review page.
+ */
+#define APPIRATER_LOCALIZED_RATE_BUTTON NSLocalizedStringFromTableInBundle(@"Rate %@", @"AppiraterLocalizable", [Appirater bundle], nil)
+#define APPIRATER_RATE_BUTTON			[NSString stringWithFormat:APPIRATER_LOCALIZED_RATE_BUTTON, APPIRATER_APP_NAME]
+
+/*!
+ Text for button to remind the user to review later.
+ */
+#define APPIRATER_RATE_LATER			NSLocalizedStringFromTableInBundle(@"Remind me later", @"AppiraterLocalizable", [Appirater bundle], nil)
+
+@interface Appirater : NSObject <UIAlertViewDelegate, SKStoreProductViewControllerDelegate> {
+
+	UIAlertView		*ratingAlert;
+}
+
+@property(nonatomic, strong) UIAlertView *ratingAlert;
+@property(nonatomic) BOOL openInAppStore;
+#if __has_feature(objc_arc_weak)
+@property(nonatomic, weak) NSObject <AppiraterDelegate> *delegate;
+#else
+@property(nonatomic, unsafe_unretained) NSObject <AppiraterDelegate> *delegate;
+#endif
+
+/*!
+ Tells Appirater that the app has launched, and on devices that do NOT
+ support multitasking, the 'uses' count will be incremented. You should
+ call this method at the end of your application delegate's
+ application:didFinishLaunchingWithOptions: method.
+ 
+ If the app has been used enough to be rated (and enough significant events),
+ you can suppress the rating alert
+ by passing NO for canPromptForRating. The rating alert will simply be postponed
+ until it is called again with YES for canPromptForRating. The rating alert
+ can also be triggered by appEnteredForeground: and userDidSignificantEvent:
+ (as long as you pass YES for canPromptForRating in those methods).
+ */
++ (void)appLaunched:(BOOL)canPromptForRating;
+
+/*!
+ Tells Appirater that the app was brought to the foreground on multitasking
+ devices. You should call this method from the application delegate's
+ applicationWillEnterForeground: method.
+ 
+ If the app has been used enough to be rated (and enough significant events),
+ you can suppress the rating alert
+ by passing NO for canPromptForRating. The rating alert will simply be postponed
+ until it is called again with YES for canPromptForRating. The rating alert
+ can also be triggered by appLaunched: and userDidSignificantEvent:
+ (as long as you pass YES for canPromptForRating in those methods).
+ */
++ (void)appEnteredForeground:(BOOL)canPromptForRating;
+
+/*!
+ Tells Appirater that the user performed a significant event. A significant
+ event is whatever you want it to be. If you're app is used to make VoIP
+ calls, then you might want to call this method whenever the user places
+ a call. If it's a game, you might want to call this whenever the user
+ beats a level boss.
+ 
+ If the user has performed enough significant events and used the app enough,
+ you can suppress the rating alert by passing NO for canPromptForRating. The
+ rating alert will simply be postponed until it is called again with YES for
+ canPromptForRating. The rating alert can also be triggered by appLaunched:
+ and appEnteredForeground: (as long as you pass YES for canPromptForRating
+ in those methods).
+ */
++ (void)userDidSignificantEvent:(BOOL)canPromptForRating;
+
+/*!
+ Tells Appirater to try and show the prompt (a rating alert). The prompt will be showed
+ if there is connection available, the user hasn't declined to rate
+ or hasn't rated current version.
+ 
+ You could call to show the prompt regardless Appirater settings,
+ e.g., in case of some special event in your app.
+ */
++ (void)tryToShowPrompt;
+
+/*!
+ Tells Appirater to show the prompt (a rating alert).
+ Similar to tryToShowPrompt, but without checks (the prompt is always displayed).
+ Passing false will hide the rate later button on the prompt.
+  
+ The only case where you should call this is if your app has an
+ explicit "Rate this app" command somewhere. This is similar to rateApp,
+ but instead of jumping to the review directly, an intermediary prompt is displayed.
+ */
++ (void)forceShowPrompt:(BOOL)displayRateLaterButton;
+
+/*!
+ Tells Appirater to open the App Store page where the user can specify a
+ rating for the app. Also records the fact that this has happened, so the
+ user won't be prompted again to rate the app.
+
+ The only case where you should call this directly is if your app has an
+ explicit "Rate this app" command somewhere.  In all other cases, don't worry
+ about calling this -- instead, just call the other functions listed above,
+ and let Appirater handle the bookkeeping of deciding when to ask the user
+ whether to rate the app.
+ */
++ (void)rateApp;
+
+/*!
+ Tells Appirater to immediately close any open rating modals (e.g. StoreKit rating VCs).
+*/
++ (void)closeModal;
+
+/*!
+ Asks Appirater if the user has declined to rate;
+*/
+- (BOOL)userHasDeclinedToRate;
+
+/*!
+ Asks Appirater if the user has rated the current version.
+ Note that this is not a guarantee that the user has actually rated the app in the 
+ app store, but they've just clicked the rate button on the Appirater dialog. 
+*/
+- (BOOL)userHasRatedCurrentVersion;
+
+@end
+
+@interface Appirater(Configuration)
+
+/*!
+ Set your Apple generated software id here.
+ */
++ (void) setAppId:(NSString*)appId;
+
+/*!
+ Users will need to have the same version of your app installed for this many
+ days before they will be prompted to rate it.
+ */
++ (void) setDaysUntilPrompt:(double)value;
+
+/*!
+ An example of a 'use' would be if the user launched the app. Bringing the app
+ into the foreground (on devices that support it) would also be considered
+ a 'use'. You tell Appirater about these events using the two methods:
+ [Appirater appLaunched:]
+ [Appirater appEnteredForeground:]
+ 
+ Users need to 'use' the same version of the app this many times before
+ before they will be prompted to rate it.
+ */
++ (void) setUsesUntilPrompt:(NSInteger)value;
+
+/*!
+ A significant event can be anything you want to be in your app. In a
+ telephone app, a significant event might be placing or receiving a call.
+ In a game, it might be beating a level or a boss. This is just another
+ layer of filtering that can be used to make sure that only the most
+ loyal of your users are being prompted to rate you on the app store.
+ If you leave this at a value of -1, then this won't be a criterion
+ used for rating. To tell Appirater that the user has performed
+ a significant event, call the method:
+ [Appirater userDidSignificantEvent:];
+ */
++ (void) setSignificantEventsUntilPrompt:(NSInteger)value;
+
+
+/*!
+ Once the rating alert is presented to the user, they might select
+ 'Remind me later'. This value specifies how long (in days) Appirater
+ will wait before reminding them.
+ */
++ (void) setTimeBeforeReminding:(double)value;
+
+/*!
+ Set customized title for alert view.
+ */
++ (void) setCustomAlertTitle:(NSString *)title;
+
+/*!
+ Set customized message for alert view.
+ */
++ (void) setCustomAlertMessage:(NSString *)message;
+
+/*!
+ Set customized cancel button title for alert view.
+ */
++ (void) setCustomAlertCancelButtonTitle:(NSString *)cancelTitle;
+
+/*!
+ Set customized rate button title for alert view.
+ */
++ (void) setCustomAlertRateButtonTitle:(NSString *)rateTitle;
+
+/*!
+ Set customized rate later button title for alert view.
+ */
++ (void) setCustomAlertRateLaterButtonTitle:(NSString *)rateLaterTitle;
+
+/*!
+ 'YES' will show the Appirater alert everytime. Useful for testing how your message
+ looks and making sure the link to your app's review page works.
+ */
++ (void) setDebug:(BOOL)debug;
+
+/*!
+ Set the delegate if you want to know when Appirater does something
+ */
++ (void)setDelegate:(id<AppiraterDelegate>)delegate;
+
+/*!
+ Set whether or not Appirater uses animation (currently respected when pushing modal StoreKit rating VCs).
+ */
++ (void)setUsesAnimation:(BOOL)animation;
+
+/*!
+ If set to YES, Appirater will open App Store link (instead of SKStoreProductViewController on iOS 6). Default YES.
+ */
++ (void)setOpenInAppStore:(BOOL)openInAppStore;
+
+/*!
+ If set to YES, the main bundle will always be used to load localized strings.
+ Set this to YES if you have provided your own custom localizations in AppiraterLocalizable.strings
+ in your main bundle.  Default is NO.
+ */
++ (void)setAlwaysUseMainBundle:(BOOL)useMainBundle;
+
+@end
+
+
+/*!
+ Methods in this interface are public out of necessity, but may change without notice
+ */
+@interface Appirater(Unsafe)
+
+/*!
+ The bundle localized strings will be loaded from.
+*/
++(NSBundle *)bundle;
+
+@end
+
+@interface Appirater(Deprecated)
+
+/*!
+ DEPRECATED: While still functional, it's better to use
+ appLaunched:(BOOL)canPromptForRating instead.
+ 
+ Calls [Appirater appLaunched:YES]. See appLaunched: for details of functionality.
+ */
++ (void)appLaunched __attribute__((deprecated)); 
+
+/*!
+ DEPRECATED: While still functional, it's better to use
+ tryToShowPrompt instead.
+ 
+ Calls [Appirater tryToShowPrompt]. See tryToShowPrompt for details of functionality.
+ */
++ (void)showPrompt __attribute__((deprecated));
+
+@end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/Appirater.m	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,732 @@
+/*
+ This file is part of Appirater.
+ 
+ Copyright (c) 2012, Arash Payan
+ All rights reserved.
+ 
+ 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.
+ */
+/*
+ * Appirater.m
+ * appirater
+ *
+ * Created by Arash Payan on 9/5/09.
+ * http://arashpayan.com
+ * Copyright 2012 Arash Payan. All rights reserved.
+ */
+
+#import "Appirater.h"
+#import <SystemConfiguration/SCNetworkReachability.h>
+#include <netinet/in.h>
+
+#if ! __has_feature(objc_arc)
+#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
+#endif
+
+NSString *const kAppiraterFirstUseDate				= @"kAppiraterFirstUseDate";
+NSString *const kAppiraterUseCount					= @"kAppiraterUseCount";
+NSString *const kAppiraterSignificantEventCount		= @"kAppiraterSignificantEventCount";
+NSString *const kAppiraterCurrentVersion			= @"kAppiraterCurrentVersion";
+NSString *const kAppiraterRatedCurrentVersion		= @"kAppiraterRatedCurrentVersion";
+NSString *const kAppiraterDeclinedToRate			= @"kAppiraterDeclinedToRate";
+NSString *const kAppiraterReminderRequestDate		= @"kAppiraterReminderRequestDate";
+
+NSString *templateReviewURL = @"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=APP_ID";
+NSString *templateReviewURLiOS7 = @"itms-apps://itunes.apple.com/app/idAPP_ID";
+NSString *templateReviewURLiOS8 = @"itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?id=APP_ID&onlyLatestVersion=true&pageNumber=0&sortOrdering=1&type=Purple+Software";
+
+static NSString *_appId;
+static double _daysUntilPrompt = 30;
+static NSInteger _usesUntilPrompt = 20;
+static NSInteger _significantEventsUntilPrompt = -1;
+static double _timeBeforeReminding = 1;
+static BOOL _debug = NO;
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0
+	static id<AppiraterDelegate> _delegate;
+#else
+	__weak static id<AppiraterDelegate> _delegate;
+#endif
+static BOOL _usesAnimation = TRUE;
+static UIStatusBarStyle _statusBarStyle;
+static BOOL _modalOpen = false;
+static BOOL _alwaysUseMainBundle = NO;
+
+@interface Appirater ()
+@property (nonatomic, copy) NSString *alertTitle;
+@property (nonatomic, copy) NSString *alertMessage;
+@property (nonatomic, copy) NSString *alertCancelTitle;
+@property (nonatomic, copy) NSString *alertRateTitle;
+@property (nonatomic, copy) NSString *alertRateLaterTitle;
+- (BOOL)connectedToNetwork;
++ (Appirater*)sharedInstance;
+- (void)showPromptWithChecks:(BOOL)withChecks
+      displayRateLaterButton:(BOOL)displayRateLaterButton;
+- (void)showRatingAlert:(BOOL)displayRateLaterButton;
+- (void)showRatingAlert;
+- (BOOL)ratingAlertIsAppropriate;
+- (BOOL)ratingConditionsHaveBeenMet;
+- (void)incrementUseCount;
+- (void)hideRatingAlert;
+@end
+
+@implementation Appirater 
+
+@synthesize ratingAlert;
+
++ (void) setAppId:(NSString *)appId {
+    _appId = appId;
+}
+
++ (void) setDaysUntilPrompt:(double)value {
+    _daysUntilPrompt = value;
+}
+
++ (void) setUsesUntilPrompt:(NSInteger)value {
+    _usesUntilPrompt = value;
+}
+
++ (void) setSignificantEventsUntilPrompt:(NSInteger)value {
+    _significantEventsUntilPrompt = value;
+}
+
++ (void) setTimeBeforeReminding:(double)value {
+    _timeBeforeReminding = value;
+}
+
++ (void) setCustomAlertTitle:(NSString *)title
+{
+    [self sharedInstance].alertTitle = title;
+}
+
++ (void) setCustomAlertMessage:(NSString *)message
+{
+    [self sharedInstance].alertMessage = message;
+}
+
++ (void) setCustomAlertCancelButtonTitle:(NSString *)cancelTitle
+{
+    [self sharedInstance].alertCancelTitle = cancelTitle;
+}
+
++ (void) setCustomAlertRateButtonTitle:(NSString *)rateTitle
+{
+    [self sharedInstance].alertRateTitle = rateTitle;
+}
+
++ (void) setCustomAlertRateLaterButtonTitle:(NSString *)rateLaterTitle
+{
+    [self sharedInstance].alertRateLaterTitle = rateLaterTitle;
+}
+
++ (void) setDebug:(BOOL)debug {
+    _debug = debug;
+}
++ (void)setDelegate:(id<AppiraterDelegate>)delegate{
+	_delegate = delegate;
+}
++ (void)setUsesAnimation:(BOOL)animation {
+	_usesAnimation = animation;
+}
++ (void)setOpenInAppStore:(BOOL)openInAppStore {
+    [Appirater sharedInstance].openInAppStore = openInAppStore;
+}
++ (void)setStatusBarStyle:(UIStatusBarStyle)style {
+	_statusBarStyle = style;
+}
++ (void)setModalOpen:(BOOL)open {
+	_modalOpen = open;
+}
++ (void)setAlwaysUseMainBundle:(BOOL)alwaysUseMainBundle {
+    _alwaysUseMainBundle = alwaysUseMainBundle;
+}
+
++ (NSBundle *)bundle
+{
+    NSBundle *bundle;
+
+    if (_alwaysUseMainBundle) {
+        bundle = [NSBundle mainBundle];
+    } else {
+        NSURL *appiraterBundleURL = [[NSBundle mainBundle] URLForResource:@"Appirater" withExtension:@"bundle"];
+
+        if (appiraterBundleURL) {
+            // Appirater.bundle will likely only exist when used via CocoaPods
+            bundle = [NSBundle bundleWithURL:appiraterBundleURL];
+        } else {
+            bundle = [NSBundle mainBundle];
+        }
+    }
+
+    return bundle;
+}
+
+- (NSString *)alertTitle
+{
+    return _alertTitle ? _alertTitle : APPIRATER_MESSAGE_TITLE;
+}
+
+- (NSString *)alertMessage
+{
+    return _alertMessage ? _alertMessage : APPIRATER_MESSAGE;
+}
+
+- (NSString *)alertCancelTitle
+{
+    return _alertCancelTitle ? _alertCancelTitle : APPIRATER_CANCEL_BUTTON;
+}
+
+- (NSString *)alertRateTitle
+{
+    return _alertRateTitle ? _alertRateTitle : APPIRATER_RATE_BUTTON;
+}
+
+- (NSString *)alertRateLaterTitle
+{
+    return _alertRateLaterTitle ? _alertRateLaterTitle : APPIRATER_RATE_LATER;
+}
+
+- (void)dealloc {
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+}
+
+- (id)init {
+    self = [super init];
+    if (self) {
+        if ([[UIDevice currentDevice].systemVersion floatValue] >= 7.0) {
+            self.openInAppStore = YES;
+        } else {
+            self.openInAppStore = NO;
+        }
+    }
+    
+    return self;
+}
+
+- (BOOL)connectedToNetwork {
+    // Create zero addy
+    struct sockaddr_in zeroAddress;
+    bzero(&zeroAddress, sizeof(zeroAddress));
+    zeroAddress.sin_len = sizeof(zeroAddress);
+    zeroAddress.sin_family = AF_INET;
+	
+    // Recover reachability flags
+    SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
+    SCNetworkReachabilityFlags flags;
+	
+    Boolean didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
+    CFRelease(defaultRouteReachability);
+	
+    if (!didRetrieveFlags)
+    {
+        NSLog(@"Error. Could not recover network reachability flags");
+        return NO;
+    }
+	
+    BOOL isReachable = flags & kSCNetworkFlagsReachable;
+    BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
+	BOOL nonWiFi = flags & kSCNetworkReachabilityFlagsTransientConnection;
+	
+	NSURL *testURL = [NSURL URLWithString:@"http://www.apple.com/"];
+	NSURLRequest *testRequest = [NSURLRequest requestWithURL:testURL  cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0];
+	NSURLConnection *testConnection = [[NSURLConnection alloc] initWithRequest:testRequest delegate:self];
+	
+    return ((isReachable && !needsConnection) || nonWiFi) ? (testConnection ? YES : NO) : NO;
+}
+
++ (Appirater*)sharedInstance {
+	static Appirater *appirater = nil;
+	if (appirater == nil)
+	{
+        static dispatch_once_t onceToken;
+        dispatch_once(&onceToken, ^{
+            appirater = [[Appirater alloc] init];
+			appirater.delegate = _delegate;
+            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillResignActive) name:
+                UIApplicationWillResignActiveNotification object:nil];
+        });
+	}
+	
+	return appirater;
+}
+
+- (void)showRatingAlert:(BOOL)displayRateLaterButton {
+  UIAlertView *alertView = nil;
+  id <AppiraterDelegate> delegate = _delegate;
+    
+  if(delegate && [delegate respondsToSelector:@selector(appiraterShouldDisplayAlert:)] && ![delegate appiraterShouldDisplayAlert:self]) {
+      return;
+  }
+  
+  if (displayRateLaterButton) {
+  	alertView = [[UIAlertView alloc] initWithTitle:self.alertTitle
+                                           message:self.alertMessage
+                                          delegate:self
+                                 cancelButtonTitle:self.alertCancelTitle
+                                 otherButtonTitles:self.alertRateTitle, self.alertRateLaterTitle, nil];
+  } else {
+  	alertView = [[UIAlertView alloc] initWithTitle:self.alertTitle
+                                           message:self.alertMessage
+                                          delegate:self
+                                 cancelButtonTitle:self.alertCancelTitle
+                                 otherButtonTitles:self.alertRateTitle, nil];
+  }
+
+	self.ratingAlert = alertView;
+    [alertView show];
+
+    if (delegate && [delegate respondsToSelector:@selector(appiraterDidDisplayAlert:)]) {
+             [delegate appiraterDidDisplayAlert:self];
+    }
+}
+
+- (void)showRatingAlert
+{
+  [self showRatingAlert:true];
+}
+
+// is this an ok time to show the alert? (regardless of whether the rating conditions have been met)
+//
+// things checked here:
+// * connectivity with network
+// * whether user has rated before
+// * whether user has declined to rate
+// * whether rating alert is currently showing visibly
+// things NOT checked here:
+// * time since first launch
+// * number of uses of app
+// * number of significant events
+// * time since last reminder
+- (BOOL)ratingAlertIsAppropriate {
+    return ([self connectedToNetwork]
+            && ![self userHasDeclinedToRate]
+            && !self.ratingAlert.visible
+            && ![self userHasRatedCurrentVersion]);
+}
+
+// have the rating conditions been met/earned? (regardless of whether this would be a moment when it's appropriate to show a new rating alert)
+//
+// things checked here:
+// * time since first launch
+// * number of uses of app
+// * number of significant events
+// * time since last reminder
+// things NOT checked here:
+// * connectivity with network
+// * whether user has rated before
+// * whether user has declined to rate
+// * whether rating alert is currently showing visibly
+- (BOOL)ratingConditionsHaveBeenMet {
+	if (_debug)
+		return YES;
+	
+	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+	
+	NSDate *dateOfFirstLaunch = [NSDate dateWithTimeIntervalSince1970:[userDefaults doubleForKey:kAppiraterFirstUseDate]];
+	NSTimeInterval timeSinceFirstLaunch = [[NSDate date] timeIntervalSinceDate:dateOfFirstLaunch];
+	NSTimeInterval timeUntilRate = 60 * 60 * 24 * _daysUntilPrompt;
+	if (timeSinceFirstLaunch < timeUntilRate)
+		return NO;
+	
+	// check if the app has been used enough
+	NSInteger useCount = [userDefaults integerForKey:kAppiraterUseCount];
+	if (useCount < _usesUntilPrompt)
+		return NO;
+	
+	// check if the user has done enough significant events
+	NSInteger sigEventCount = [userDefaults integerForKey:kAppiraterSignificantEventCount];
+	if (sigEventCount < _significantEventsUntilPrompt)
+		return NO;
+	
+	// if the user wanted to be reminded later, has enough time passed?
+	NSDate *reminderRequestDate = [NSDate dateWithTimeIntervalSince1970:[userDefaults doubleForKey:kAppiraterReminderRequestDate]];
+	NSTimeInterval timeSinceReminderRequest = [[NSDate date] timeIntervalSinceDate:reminderRequestDate];
+	NSTimeInterval timeUntilReminder = 60 * 60 * 24 * _timeBeforeReminding;
+	if (timeSinceReminderRequest < timeUntilReminder)
+		return NO;
+	
+	return YES;
+}
+
+- (void)incrementUseCount {
+	// get the app's version
+	NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleVersionKey];
+	
+	// get the version number that we've been tracking
+	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+	NSString *trackingVersion = [userDefaults stringForKey:kAppiraterCurrentVersion];
+	if (trackingVersion == nil)
+	{
+		trackingVersion = version;
+		[userDefaults setObject:version forKey:kAppiraterCurrentVersion];
+	}
+	
+	if (_debug)
+		NSLog(@"APPIRATER Tracking version: %@", trackingVersion);
+	
+	if ([trackingVersion isEqualToString:version])
+	{
+		// check if the first use date has been set. if not, set it.
+		NSTimeInterval timeInterval = [userDefaults doubleForKey:kAppiraterFirstUseDate];
+		if (timeInterval == 0)
+		{
+			timeInterval = [[NSDate date] timeIntervalSince1970];
+			[userDefaults setDouble:timeInterval forKey:kAppiraterFirstUseDate];
+		}
+		
+		// increment the use count
+		NSInteger useCount = [userDefaults integerForKey:kAppiraterUseCount];
+		useCount++;
+		[userDefaults setInteger:useCount forKey:kAppiraterUseCount];
+		if (_debug)
+			NSLog(@"APPIRATER Use count: %@", @(useCount));
+	}
+	else
+	{
+		// it's a new version of the app, so restart tracking
+		[userDefaults setObject:version forKey:kAppiraterCurrentVersion];
+		[userDefaults setDouble:[[NSDate date] timeIntervalSince1970] forKey:kAppiraterFirstUseDate];
+		[userDefaults setInteger:1 forKey:kAppiraterUseCount];
+		[userDefaults setInteger:0 forKey:kAppiraterSignificantEventCount];
+		[userDefaults setBool:NO forKey:kAppiraterRatedCurrentVersion];
+		[userDefaults setBool:NO forKey:kAppiraterDeclinedToRate];
+		[userDefaults setDouble:0 forKey:kAppiraterReminderRequestDate];
+	}
+	
+	[userDefaults synchronize];
+}
+
+- (void)incrementSignificantEventCount {
+	// get the app's version
+	NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleVersionKey];
+	
+	// get the version number that we've been tracking
+	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+	NSString *trackingVersion = [userDefaults stringForKey:kAppiraterCurrentVersion];
+	if (trackingVersion == nil)
+	{
+		trackingVersion = version;
+		[userDefaults setObject:version forKey:kAppiraterCurrentVersion];
+	}
+	
+	if (_debug)
+		NSLog(@"APPIRATER Tracking version: %@", trackingVersion);
+	
+	if ([trackingVersion isEqualToString:version])
+	{
+		// check if the first use date has been set. if not, set it.
+		NSTimeInterval timeInterval = [userDefaults doubleForKey:kAppiraterFirstUseDate];
+		if (timeInterval == 0)
+		{
+			timeInterval = [[NSDate date] timeIntervalSince1970];
+			[userDefaults setDouble:timeInterval forKey:kAppiraterFirstUseDate];
+		}
+		
+		// increment the significant event count
+		NSInteger sigEventCount = [userDefaults integerForKey:kAppiraterSignificantEventCount];
+		sigEventCount++;
+		[userDefaults setInteger:sigEventCount forKey:kAppiraterSignificantEventCount];
+		if (_debug)
+			NSLog(@"APPIRATER Significant event count: %@", @(sigEventCount));
+	}
+	else
+	{
+		// it's a new version of the app, so restart tracking
+		[userDefaults setObject:version forKey:kAppiraterCurrentVersion];
+		[userDefaults setDouble:0 forKey:kAppiraterFirstUseDate];
+		[userDefaults setInteger:0 forKey:kAppiraterUseCount];
+		[userDefaults setInteger:1 forKey:kAppiraterSignificantEventCount];
+		[userDefaults setBool:NO forKey:kAppiraterRatedCurrentVersion];
+		[userDefaults setBool:NO forKey:kAppiraterDeclinedToRate];
+		[userDefaults setDouble:0 forKey:kAppiraterReminderRequestDate];
+	}
+	
+	[userDefaults synchronize];
+}
+
+- (void)incrementAndRate:(BOOL)canPromptForRating {
+	[self incrementUseCount];
+	
+	if (canPromptForRating &&
+        [self ratingConditionsHaveBeenMet] &&
+        [self ratingAlertIsAppropriate])
+	{
+        dispatch_async(dispatch_get_main_queue(),
+                       ^{
+                           [self showRatingAlert];
+                       });
+	}
+}
+
+- (void)incrementSignificantEventAndRate:(BOOL)canPromptForRating {
+	[self incrementSignificantEventCount];
+	
+    if (canPromptForRating &&
+        [self ratingConditionsHaveBeenMet] &&
+        [self ratingAlertIsAppropriate])
+	{
+        dispatch_async(dispatch_get_main_queue(),
+                       ^{
+                           [self showRatingAlert];
+                       });
+	}
+}
+
+- (BOOL)userHasDeclinedToRate {
+    return [[NSUserDefaults standardUserDefaults] boolForKey:kAppiraterDeclinedToRate];
+}
+
+- (BOOL)userHasRatedCurrentVersion {
+    return [[NSUserDefaults standardUserDefaults] boolForKey:kAppiraterRatedCurrentVersion];
+}
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-implementations"
++ (void)appLaunched {
+	[Appirater appLaunched:YES];
+}
+#pragma GCC diagnostic pop
+
++ (void)appLaunched:(BOOL)canPromptForRating {
+    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0),
+                   ^{
+                       Appirater *a = [Appirater sharedInstance];
+                       if (_debug) {
+                           dispatch_async(dispatch_get_main_queue(),
+                                          ^{
+                                              [a showRatingAlert];
+                                          });
+                       } else {
+                           [a incrementAndRate:canPromptForRating]; 
+                       }
+                   });
+}
+
+- (void)hideRatingAlert {
+	if (self.ratingAlert.visible) {
+		if (_debug)
+			NSLog(@"APPIRATER Hiding Alert");
+		[self.ratingAlert dismissWithClickedButtonIndex:-1 animated:NO];
+	}	
+}
+
++ (void)appWillResignActive {
+	if (_debug)
+		NSLog(@"APPIRATER appWillResignActive");
+	[[Appirater sharedInstance] hideRatingAlert];
+}
+
++ (void)appEnteredForeground:(BOOL)canPromptForRating {
+    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0),
+                   ^{
+                       [[Appirater sharedInstance] incrementAndRate:canPromptForRating];
+                   });
+}
+
++ (void)userDidSignificantEvent:(BOOL)canPromptForRating {
+    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0),
+                   ^{
+                       [[Appirater sharedInstance] incrementSignificantEventAndRate:canPromptForRating];
+                   });
+}
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-implementations"
++ (void)showPrompt {
+  [Appirater tryToShowPrompt];
+}
+#pragma GCC diagnostic pop
+
++ (void)tryToShowPrompt {
+  [[Appirater sharedInstance] showPromptWithChecks:true
+                            displayRateLaterButton:true];
+}
+
++ (void)forceShowPrompt:(BOOL)displayRateLaterButton {
+  [[Appirater sharedInstance] showPromptWithChecks:false
+                            displayRateLaterButton:displayRateLaterButton];
+}
+
+- (void)showPromptWithChecks:(BOOL)withChecks
+      displayRateLaterButton:(BOOL)displayRateLaterButton {
+  if (withChecks == NO || [self ratingAlertIsAppropriate]) {
+    [self showRatingAlert:displayRateLaterButton];
+  }
+}
+
++ (id)getRootViewController {
+    UIWindow *window = [[UIApplication sharedApplication] keyWindow];
+    if (window.windowLevel != UIWindowLevelNormal) {
+        NSArray *windows = [[UIApplication sharedApplication] windows];
+        for(window in windows) {
+            if (window.windowLevel == UIWindowLevelNormal) {
+                break;
+            }
+        }
+    }
+    
+    return [Appirater iterateSubViewsForViewController:window]; // iOS 8+ deep traverse
+}
+
++ (id)iterateSubViewsForViewController:(UIView *) parentView {
+    for (UIView *subView in [parentView subviews]) {
+        UIResponder *responder = [subView nextResponder];
+        if([responder isKindOfClass:[UIViewController class]]) {
+            return [self topMostViewController: (UIViewController *) responder];
+        }
+        id found = [Appirater iterateSubViewsForViewController:subView];
+        if( nil != found) {
+            return found;
+        }
+    }
+    return nil;
+}
+
++ (UIViewController *) topMostViewController: (UIViewController *) controller {
+	BOOL isPresenting = NO;
+	do {
+		// this path is called only on iOS 6+, so -presentedViewController is fine here.
+		UIViewController *presented = [controller presentedViewController];
+		isPresenting = presented != nil;
+		if(presented != nil) {
+			controller = presented;
+		}
+		
+	} while (isPresenting);
+	
+	return controller;
+}
+
++ (void)rateApp {
+	
+	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+	[userDefaults setBool:YES forKey:kAppiraterRatedCurrentVersion];
+	[userDefaults synchronize];
+
+	//Use the in-app StoreKit view if available (iOS 6) and imported. This works in the simulator.
+	if (![Appirater sharedInstance].openInAppStore && NSStringFromClass([SKStoreProductViewController class]) != nil) {
+		
+		SKStoreProductViewController *storeViewController = [[SKStoreProductViewController alloc] init];
+		NSNumber *appId = [NSNumber numberWithInteger:_appId.integerValue];
+		[storeViewController loadProductWithParameters:@{SKStoreProductParameterITunesItemIdentifier:appId} completionBlock:nil];
+		storeViewController.delegate = self.sharedInstance;
+        
+        id <AppiraterDelegate> delegate = self.sharedInstance.delegate;
+		if ([delegate respondsToSelector:@selector(appiraterWillPresentModalView:animated:)]) {
+			[delegate appiraterWillPresentModalView:self.sharedInstance animated:_usesAnimation];
+		}
+		[[self getRootViewController] presentViewController:storeViewController animated:_usesAnimation completion:^{
+			[self setModalOpen:YES];
+			//Temporarily use a black status bar to match the StoreKit view.
+			[self setStatusBarStyle:[UIApplication sharedApplication].statusBarStyle];
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
+			[[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent animated:_usesAnimation];
+#endif
+		}];
+	
+	//Use the standard openUrl method if StoreKit is unavailable.
+	} else {
+		
+		#if TARGET_IPHONE_SIMULATOR
+		NSLog(@"APPIRATER NOTE: iTunes App Store is not supported on the iOS simulator. Unable to open App Store page.");
+		#else
+		NSString *reviewURL = [templateReviewURL stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%@", _appId]];
+
+		// iOS 7 needs a different templateReviewURL @see https://github.com/arashpayan/appirater/issues/131
+        // Fixes condition @see https://github.com/arashpayan/appirater/issues/205
+		if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0 && [[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) {
+			reviewURL = [templateReviewURLiOS7 stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%@", _appId]];
+		}
+        // iOS 8 needs a different templateReviewURL also @see https://github.com/arashpayan/appirater/issues/182
+        else if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
+        {
+            reviewURL = [templateReviewURLiOS8 stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%@", _appId]];
+        }
+
+		[[UIApplication sharedApplication] openURL:[NSURL URLWithString:reviewURL]];
+		#endif
+	}
+}
+
+- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
+	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+    
+    id <AppiraterDelegate> delegate = _delegate;
+	
+	switch (buttonIndex) {
+		case 0:
+		{
+			// they don't want to rate it
+			[userDefaults setBool:YES forKey:kAppiraterDeclinedToRate];
+			[userDefaults synchronize];
+			if(delegate && [delegate respondsToSelector:@selector(appiraterDidDeclineToRate:)]){
+				[delegate appiraterDidDeclineToRate:self];
+			}
+			break;
+		}
+		case 1:
+		{
+			// they want to rate it
+			[Appirater rateApp];
+			if(delegate&& [delegate respondsToSelector:@selector(appiraterDidOptToRate:)]){
+				[delegate appiraterDidOptToRate:self];
+			}
+			break;
+		}
+		case 2:
+			// remind them later
+			[userDefaults setDouble:[[NSDate date] timeIntervalSince1970] forKey:kAppiraterReminderRequestDate];
+			[userDefaults synchronize];
+			if(delegate && [delegate respondsToSelector:@selector(appiraterDidOptToRemindLater:)]){
+				[delegate appiraterDidOptToRemindLater:self];
+			}
+			break;
+		default:
+			break;
+	}
+}
+
+//Delegate call from the StoreKit view.
+- (void)productViewControllerDidFinish:(SKStoreProductViewController *)viewController {
+	[Appirater closeModal];
+}
+
+//Close the in-app rating (StoreKit) view and restore the previous status bar style.
++ (void)closeModal {
+	if (_modalOpen) {
+		[[UIApplication sharedApplication]setStatusBarStyle:_statusBarStyle animated:_usesAnimation];
+		BOOL usedAnimation = _usesAnimation;
+		[self setModalOpen:NO];
+		
+		// get the top most controller (= the StoreKit Controller) and dismiss it
+		UIViewController *presentingController = [UIApplication sharedApplication].keyWindow.rootViewController;
+		presentingController = [self topMostViewController: presentingController];
+		[presentingController dismissViewControllerAnimated:_usesAnimation completion:^{
+            id <AppiraterDelegate> delegate = self.sharedInstance.delegate;
+			if ([delegate respondsToSelector:@selector(appiraterDidDismissModalView:animated:)]) {
+				[delegate appiraterDidDismissModalView:(Appirater *)self animated:usedAnimation];
+			}
+		}];
+		[self.class setStatusBarStyle:(UIStatusBarStyle)nil];
+	}
+}
+
+@end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater/AppiraterDelegate.h	Mon Nov 16 22:57:24 2015 +0300
@@ -0,0 +1,23 @@
+//
+//  AppiraterDelegate.h
+//  Banana Stand
+//
+//  Created by Robert Haining on 9/25/12.
+//  Copyright (c) 2012 News.me. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class Appirater;
+
+@protocol AppiraterDelegate <NSObject>
+
+@optional
+-(BOOL)appiraterShouldDisplayAlert:(Appirater *)appirater;
+-(void)appiraterDidDisplayAlert:(Appirater *)appirater;
+-(void)appiraterDidDeclineToRate:(Appirater *)appirater;
+-(void)appiraterDidOptToRate:(Appirater *)appirater;
+-(void)appiraterDidOptToRemindLater:(Appirater *)appirater;
+-(void)appiraterWillPresentModalView:(Appirater *)appirater animated:(BOOL)animated;
+-(void)appiraterDidDismissModalView:(Appirater *)appirater animated:(BOOL)animated;
+@end
--- a/project_files/HedgewarsMobile/Classes/CreationChamber.m	Tue Sep 08 19:20:58 2015 +0300
+++ b/project_files/HedgewarsMobile/Classes/CreationChamber.m	Mon Nov 16 22:57:24 2015 +0300
@@ -57,7 +57,7 @@
         [[NSFileManager defaultManager] removeItemAtPath:SCHEMES_DIRECTORY() error:NULL];
     NSArray *schemeNames = [[NSArray alloc] initWithObjects:@"Default",@"Pro Mode",@"Shoppa",@"Clean Slate",
                             @"Minefield",@"Barrel Mayhem",@"Tunnel Hogs",@"Fort Mode",@"Timeless",
-                            @"Thinking with Portals",@"King Mode",nil];
+                            @"Thinking with Portals",@"King Mode",@"Construction Mode",nil];
     index = 0;
     for (NSString *name in schemeNames)
         [self createSchemeNamed:name ofType:index++];
@@ -65,7 +65,7 @@
 
     // WEAPONS - always overwrite as merge is not needed (missing weaps are 0ed automatically)
     NSArray *weaponNames = [[NSArray alloc] initWithObjects:@"Default",@"Crazy",@"Pro Mode",@"Shoppa",@"Clean Slate",
-                            @"Minefield",@"Thinking with Portals",nil];
+                            @"Minefield",@"Thinking with Portals",@"One of Everything",@"Highlander",@"Construction Mode",@"Shoppa Pro",nil];
     index = 0;
     for (NSString *name in weaponNames)
         [self createWeaponNamed:name ofType:index++];
@@ -241,6 +241,30 @@
             delay = [[NSString alloc] initWithBytes:AMMOLINE_PORTALS_DELAY length:ammolineSize encoding:NSUTF8StringEncoding];
             crate = [[NSString alloc] initWithBytes:AMMOLINE_PORTALS_CRATE length:ammolineSize encoding:NSUTF8StringEncoding];
             break;
+        case 7:  //one of everything
+            qt = [[NSString alloc] initWithBytes:AMMOLINE_ONEEVERY_QT length:ammolineSize encoding:NSUTF8StringEncoding];
+            prob = [[NSString alloc] initWithBytes:AMMOLINE_ONEEVERY_PROB length:ammolineSize encoding:NSUTF8StringEncoding];
+            delay = [[NSString alloc] initWithBytes:AMMOLINE_ONEEVERY_DELAY length:ammolineSize encoding:NSUTF8StringEncoding];
+            crate = [[NSString alloc] initWithBytes:AMMOLINE_ONEEVERY_CRATE length:ammolineSize encoding:NSUTF8StringEncoding];
+            break;
+        case 8:  //highlander
+            qt = [[NSString alloc] initWithBytes:AMMOLINE_HIGHLANDER_QT length:ammolineSize encoding:NSUTF8StringEncoding];
+            prob = [[NSString alloc] initWithBytes:AMMOLINE_HIGHLANDER_PROB length:ammolineSize encoding:NSUTF8StringEncoding];
+            delay = [[NSString alloc] initWithBytes:AMMOLINE_HIGHLANDER_DELAY length:ammolineSize encoding:NSUTF8StringEncoding];
+            crate = [[NSString alloc] initWithBytes:AMMOLINE_HIGHLANDER_CRATE length:ammolineSize encoding:NSUTF8StringEncoding];
+            break;
+        case 9:  //construction mode
+            qt = [[NSString alloc] initWithBytes:AMMOLINE_CONSTRUCTION_QT length:ammolineSize encoding:NSUTF8StringEncoding];
+            prob = [[NSString alloc] initWithBytes:AMMOLINE_CONSTRUCTION_PROB length:ammolineSize encoding:NSUTF8StringEncoding];
+            delay = [[NSString alloc] initWithBytes:AMMOLINE_CONSTRUCTION_DELAY length:ammolineSize encoding:NSUTF8StringEncoding];
+            crate = [[NSString alloc] initWithBytes:AMMOLINE_CONSTRUCTION_CRATE length:ammolineSize encoding:NSUTF8StringEncoding];
+            break;
+        case 10:  //shoppa pro
+            qt = [[NSString alloc] initWithBytes:AMMOLINE_SHOPPAPRO_QT length:ammolineSize encoding:NSUTF8StringEncoding];
+            prob = [[NSString alloc] initWithBytes:AMMOLINE_SHOPPAPRO_PROB length:ammolineSize encoding:NSUTF8StringEncoding];
+            delay = [[NSString alloc] initWithBytes:AMMOLINE_SHOPPAPRO_DELAY length:ammolineSize encoding:NSUTF8StringEncoding];
+            crate = [[NSString alloc] initWithBytes:AMMOLINE_SHOPPAPRO_CRATE length:ammolineSize encoding:NSUTF8StringEncoding];
+            break;
     }
 
     NSDictionary *theWeapon = [[NSDictionary alloc] initWithObjectsAndKeys: qt,@"ammostore_initialqt",
@@ -303,6 +327,7 @@
             [basicArray replaceObjectAtIndex:9 withObject:[NSNumber numberWithInt:25]];
             [basicArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithInt:0]];
             [basicArray replaceObjectAtIndex:13 withObject:[NSNumber numberWithInt:0]];
+            [basicArray replaceObjectAtIndex:15 withObject:[NSNumber numberWithInt:8]];
             [gamemodArray replaceObjectAtIndex:1 withObject:[NSNumber numberWithBool:YES]];
             [gamemodArray replaceObjectAtIndex:2 withObject:[NSNumber numberWithBool:YES]];
             [gamemodArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithBool:YES]];
@@ -342,6 +367,7 @@
             [basicArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithInt:10]];
             [basicArray replaceObjectAtIndex:12 withObject:[NSNumber numberWithInt:10]];
             [basicArray replaceObjectAtIndex:13 withObject:[NSNumber numberWithInt:10]];
+            [basicArray replaceObjectAtIndex:15 withObject:[NSNumber numberWithInt:4]];
             [gamemodArray replaceObjectAtIndex:2 withObject:[NSNumber numberWithBool:YES]];
             [gamemodArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithBool:YES]];
             [gamemodArray replaceObjectAtIndex:14 withObject:[NSNumber numberWithBool:YES]];
@@ -373,6 +399,7 @@
             [basicArray replaceObjectAtIndex:10 withObject:[NSNumber numberWithInt:4]];
             [basicArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithInt:5]];
             [basicArray replaceObjectAtIndex:13 withObject:[NSNumber numberWithInt:5]];
+            [basicArray replaceObjectAtIndex:15 withObject:[NSNumber numberWithInt:4]];
             [gamemodArray replaceObjectAtIndex:9 withObject:[NSNumber numberWithBool:YES]];
             [gamemodArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithBool:YES]];
             break;
@@ -380,6 +407,15 @@
             [gamemodArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithBool:YES]];
             [gamemodArray replaceObjectAtIndex:12 withObject:[NSNumber numberWithBool:YES]];
             break;
+        case 11: // construction mode
+            [basicArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithInt:0]];
+            [basicArray replaceObjectAtIndex:13 withObject:[NSNumber numberWithInt:0]];
+            [gamemodArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithBool:YES]];
+            [gamemodArray replaceObjectAtIndex:15 withObject:[NSNumber numberWithBool:YES]];
+            [gamemodArray replaceObjectAtIndex:16 withObject:[NSNumber numberWithBool:YES]];
+            [gamemodArray replaceObjectAtIndex:18 withObject:[NSNumber numberWithBool:YES]];
+            [gamemodArray replaceObjectAtIndex:20 withObject:[NSNumber numberWithBool:YES]];
+            break;
     }
 
     NSMutableDictionary *theScheme = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
--- a/project_files/HedgewarsMobile/Classes/EditableCellView.m	Tue Sep 08 19:20:58 2015 +0300
+++ b/project_files/HedgewarsMobile/Classes/EditableCellView.m	Mon Nov 16 22:57:24 2015 +0300
@@ -18,7 +18,7 @@
 
 
 #import "EditableCellView.h"
-
+#import "UITableViewCell+FindTable.h"
 
 @implementation EditableCellView
 @synthesize delegate, textField, titleLabel, minimumCharacters, maximumCharacters, respectEditing, oldValue;
@@ -103,13 +103,13 @@
 -(BOOL) textFieldShouldBeginEditing:(UITextField *)aTextField {
     return (delegate != nil) &&
            [delegate respondsToSelector:@selector(saveTextFieldValue:withTag:)] &&
-           (respectEditing) ? ((UITableView*)[self superview]).editing : YES;
+           (respectEditing) ? [self findTable].editing : YES;
 }
 
 // the textfield is being modified, update the navigation controller
 -(void) textFieldDidBeginEditing:(UITextField *)aTextField{
     // don't interact with table below
-    ((UITableView*)[self superview]).scrollEnabled = NO;
+    [self findTable].scrollEnabled = NO;
 
     self.oldValue = self.textField.text;
 
@@ -147,9 +147,9 @@
         [self save:aTextField];
 
     // restores default behaviour on caller
-    ((UITableView*)[self superview]).scrollEnabled = YES;
-    [(UITableViewController *)delegate navigationItem].rightBarButtonItem = [(UITableViewController *)delegate navigationItem].backBarButtonItem;
-    [(UITableViewController *)delegate navigationItem].leftBarButtonItem = nil;
+    [self findTable].scrollEnabled = YES;
+    [(UITableViewController *)delegate navigationItem].leftBarButtonItem = [(UITableViewController *)delegate navigationItem].backBarButtonItem;
+    [(UITableViewController *)delegate navigationItem].rightBarButtonItem = nil;
 }
 
 #pragma mark -
--- a/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.m	Tue Sep 08 19:20:58 2015 +0300
+++ b/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.m	Mon Nov 16 22:57:24 2015 +0300
@@ -96,8 +96,8 @@
     for (int i = 0; i < numberOfPlayingHogs; i++) {
         NSDictionary *hog = [hogs objectAtIndex:i];
 
-        NSString *hogLevelHealthAndName = [[NSString alloc] initWithFormat:@"eaddhh %@ %d %@",
-                                           [hog objectForKey:@"level"], initialHealth, [hog objectForKey:@"hogname"]];
+        NSString *hogLevelHealthAndName = [[NSString alloc] initWithFormat:@"eaddhh %@ %ld %@",
+                                           [hog objectForKey:@"level"], (long)initialHealth, [hog objectForKey:@"hogname"]];
         [self sendToEngine: hogLevelHealthAndName];
         [hogLevelHealthAndName release];
 
@@ -197,7 +197,7 @@
 
 // wrapper that computes the length of the message and then sends the command string, saving the command on a file
 -(int) sendToEngine:(NSString *)string {
-    uint8_t length = [string length];
+    uint8_t length = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
 
     [self dumpRawData:[string UTF8String] ofSize:length];
     SDLNet_TCP_Send(csd, &length, 1);
@@ -206,7 +206,7 @@
 
 // wrapper that computes the length of the message and then sends the command string, skipping file writing
 -(int) sendToEngineNoSave:(NSString *)string {
-    uint8_t length = [string length];
+    uint8_t length = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
 
     SDLNet_TCP_Send(csd, &length, 1);
     return SDLNet_TCP_Send(csd, [string UTF8String], length);
@@ -214,7 +214,8 @@
 
 // this is launched as thread and handles all IPC with engine
 -(void) engineProtocol:(id) object {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    @autoreleasepool {
+    
     NSDictionary *gameConfig = (NSDictionary *)object;
     NSMutableArray *statsArray = nil;
     TCPsocket sd;
@@ -240,7 +241,7 @@
 
     // Open a connection with the IP provided (listen on the host's port)
     if (!(sd = SDLNet_TCP_Open(&ip)) && !clientQuit) {
-        DLog(@"SDLNet_TCP_Open: %s %\n", SDLNet_GetError(), self.enginePort);
+        DLog(@"SDLNet_TCP_Open: %s %d\n", SDLNet_GetError(), self.enginePort);
         clientQuit = YES;
     }
 
@@ -340,19 +341,25 @@
                 NSString *tempStr = [NSString stringWithUTF8String:&buffer[2]];
                 NSArray *info = [tempStr componentsSeparatedByString:@" "];
                 NSString *arg = [info objectAtIndex:0];
-                int index = [arg length] + 3;
+                int index = [arg lengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 3;
                 switch (buffer[1]) {
                     case 'r':           // winning team
                         [statsArray insertObject:[NSString stringWithUTF8String:&buffer[2]] atIndex:1];
                         break;
                     case 'D':           // best shot
-                        [statsArray addObject:[NSString stringWithFormat:@"The best shot award won by %s (with %@ points)", &buffer[index], arg]];
+                    {
+                        NSString *hogName = [NSString stringWithUTF8String:&buffer[index]];
+                        [statsArray addObject:[NSString stringWithFormat:NSLocalizedString(@"The best shot award won by %@ (with %@ points)", nil), hogName, arg]];
                         break;
+                    }
                     case 'k':           // best hedgehog
-                        [statsArray addObject:[NSString stringWithFormat:@"The best killer is %s with %@ kill(s) in a turn", &buffer[index], arg]];
+                    {
+                        NSString *hogName = [NSString stringWithUTF8String:&buffer[index]];
+                        [statsArray addObject:[NSString stringWithFormat:NSLocalizedString(@"The best killer is %@ with %@ kill(s) in a turn", nil), hogName, arg]];
                         break;
+                    }
                     case 'K':           // number of hogs killed
-                        [statsArray addObject:[NSString stringWithFormat:@"%@ hedgehog(s) were killed during this round", arg]];
+                        [statsArray addObject:[NSString stringWithFormat:NSLocalizedString(@"%@ hedgehog(s) were killed during this round", nil), arg]];
                         break;
                     case 'H':           // team health/graph
                         break;
@@ -363,14 +370,23 @@
                         [[statsArray objectAtIndex:0] addObject:tempStr];
                         break;
                     case 's':           // self damage
-                        [statsArray addObject:[NSString stringWithFormat:@"%s thought it's good to shoot his own hedgehogs with %@ points", &buffer[index], arg]];
+                    {
+                        NSString *hogName = [NSString stringWithUTF8String:&buffer[index]];
+                        [statsArray addObject:[NSString stringWithFormat:NSLocalizedString(@"%@ thought it's good to shoot his own hedgehogs with %@ points", nil), hogName, arg]];
                         break;
+                    }
                     case 'S':           // friendly fire
-                        [statsArray addObject:[NSString stringWithFormat:@"%s killed %@ of his own hedgehogs", &buffer[index], arg]];
+                    {
+                        NSString *hogName = [NSString stringWithUTF8String:&buffer[index]];
+                        [statsArray addObject:[NSString stringWithFormat:NSLocalizedString(@"%@ killed %@ of his own hedgehogs", nil), hogName, arg]];
                         break;
+                    }
                     case 'B':           // turn skipped
-                        [statsArray addObject:[NSString stringWithFormat:@"%s was scared and skipped turn %@ times", &buffer[index], arg]];
+                    {
+                        NSString *hogName = [NSString stringWithUTF8String:&buffer[index]];
+                        [statsArray addObject:[NSString stringWithFormat:NSLocalizedString(@"%@ was scared and skipped turn %@ times", nil), hogName, arg]];
                         break;
+                    }
                     default:
                         DLog(@"Unhandled stat message, see statsPage.cpp");
                         break;
@@ -403,8 +419,9 @@
     [HWUtils freePort:self.enginePort];
     SDLNet_TCP_Close(csd);
     SDLNet_Quit();
+    
+    }
 
-    [pool release];
     // Invoking this method should be avoided as it does not give your thread a chance
     // to clean up any resources it allocated during its execution.
     //[NSThread exit];
--- a/project_files/HedgewarsMobile/Classes/ExtraCategories.h	Tue Sep 08 19:20:58 2015 +0300
+++ b/project_files/HedgewarsMobile/Classes/ExtraCategories.h	Mon Nov 16 22:57:24 2015 +0300
@@ -50,6 +50,9 @@
 
 -(id) initWithFrame:(CGRect) frame andTitle:(NSString *)title;
 
+- (void)applyBlackQuickStyle;
+- (void)applyDarkBlueQuickStyle;
+
 @end
 
 
--- a/project_files/HedgewarsMobile/Classes/ExtraCategories.m	Tue Sep 08 19:20:58 2015 +0300
+++ b/project_files/HedgewarsMobile/Classes/ExtraCategories.m	Mon Nov 16 22:57:24 2015 +0300
@@ -27,17 +27,18 @@
 
 -(CGFloat) safeScale {
     CGFloat theScale = 1.0f;
-    if ([self respondsToSelector:@selector(scale)])
-         theScale = [self scale];
+//    if ([self respondsToSelector:@selector(scale)])
+//         theScale = [self scale];
     return theScale;
 }
 
 -(CGRect) safeBounds {
-    CGRect original = [self bounds];
-    if (IS_ON_PORTRAIT())
-        return original;
-    else
-        return CGRectMake(original.origin.x, original.origin.y, original.size.height, original.size.width);
+    return [self bounds];
+//    CGRect original = [self bounds];
+//    if (IS_ON_PORTRAIT())
+//        return original;
+//    else
+//        return CGRectMake(original.origin.x, original.origin.y, original.size.height, original.size.width);
 }
 
 @end
@@ -99,17 +100,35 @@
 -(id) initWithFrame:(CGRect) frame andTitle:(NSString *)title {
     [self initWithFrame:frame];
     [self setTitle:title forState:UIControlStateNormal];
+    [self applyBlackQuickStyle];
+
+    return self;
+}
+
+- (void)applyBlackQuickStyle
+{
     [self setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
     [self setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted];
     self.titleLabel.font = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]];
     self.backgroundColor = [UIColor blackColorTransparent];
-
-    [self.layer setBorderWidth:1];
+    
+    [self.layer setBorderWidth:1.0f];
     [self.layer setBorderColor:[[UIColor darkYellowColor] CGColor]];
     [self.layer setCornerRadius:9.0f];
     [self.layer setMasksToBounds:YES];
+}
 
-    return self;
+- (void)applyDarkBlueQuickStyle
+{
+    [self setTitleColor:[UIColor darkYellowColor] forState:UIControlStateNormal];
+    [self setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted];
+    self.titleLabel.font = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]];
+    self.backgroundColor = [UIColor darkBlueColorTransparent];
+    
+    [self.layer setBorderWidth:2.0f];
+    [self.layer setBorderColor:[[UIColor darkYellowColor] CGColor]];
+    [self.layer setCornerRadius:9.0f];
+    [self.layer setMasksToBounds:YES];
 }
 
 @end
--- a/project_files/HedgewarsMobile/Classes/FlagsViewController.m	Tue Sep 08 19:20:58 2015 +0300
+++ b/project_files/HedgewarsMobile/Classes/FlagsViewController.m	Mon Nov 16 22:57:24 2015 +0300
@@ -131,10 +131,10 @@
 #pragma mark -
 #pragma mark Table view delegate
 -(void) tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
-    int newRow = [indexPath row];
-    int oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
-    int newSection = [indexPath section];
-    int oldSection = (lastIndexPath != nil) ? [lastIndexPath section] : -1;
+    NSInteger newRow = [indexPath row];
+    NSInteger oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
+    NSInteger newSection = [indexPath section];
+    NSInteger oldSection = (lastIndexPath != nil) ? [lastIndexPath section] : -1;
 
     if (newRow != oldRow || newSection != oldSection) {
         NSString *flag = nil;
--- a/project_files/HedgewarsMobile/Classes/FortsViewController.m	Tue Sep 08 19:20:58 2015 +0300
+++ b/project_files/HedgewarsMobile/Classes/FortsViewController.m	Mon Nov 16 22:57:24 2015 +0300
@@ -38,11 +38,13 @@
 
     NSArray *directoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:FORTS_DIRECTORY() error:NULL];
     NSMutableArray *filteredContents = [[NSMutableArray alloc] initWithCapacity:([directoryContents count] / IMGNUM_PER_FORT)];
-    // we need to remove the double entries and the L.png suffix
-    for (NSUInteger i = 0; i < [directoryContents count]; i++) {
-        if (i % IMGNUM_PER_FORT == IMGNUM_PER_FORT-1) {
-            NSString *currentName = [directoryContents objectAtIndex:i];
-            NSString *correctName = [currentName substringToIndex:([currentName length] - 5)];
+    // we assume here that fort's images has one image with the 'L.png' suffix and we remove this suffix to get the correct name
+    for (NSUInteger i = 0; i < [directoryContents count]; i++)
+    {
+        NSString *currentName = [directoryContents objectAtIndex:i];
+        if ([currentName rangeOfString:@"L.png"].location != NSNotFound)
+        {
+            NSString *correctName = [currentName stringByReplacingOccurrencesOfString:@"L.png" withString:@""];
             [filteredContents addObject:correctName];
         }
     }
@@ -106,8 +108,8 @@
 #pragma mark -
 #pragma mark Table view delegate
 -(void) tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
-    int newRow = [indexPath row];
-    int oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
+    NSInteger newRow = [indexPath row];
+    NSInteger oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
 
     if (newRow != oldRow) {
         // if the two selected rows differ update data on the hog dictionary and reload table content
--- a/project_files/HedgewarsMobile/Classes/GameConfigViewController-iPad.xib	Tue Sep 08 19:20:58 2015 +0300
+++ b/project_files/HedgewarsMobile/Classes/GameConfigViewController-iPad.xib	Mon Nov 16 22:57:24 2015 +0300
@@ -1,34 +1,28 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="7.10">
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="8.00">
 	<data>
-		<int key="IBDocument.SystemTarget">1056</int>
-		<string key="IBDocument.SystemVersion">10K549</string>
-		<string key="IBDocument.InterfaceBuilderVersion">823</string>
-		<string key="IBDocument.AppKitVersion">1038.36</string>
-		<string key="IBDocument.HIToolboxVersion">461.00</string>
+		<int key="IBDocument.SystemTarget">1792</int>
+		<string key="IBDocument.SystemVersion">14E46</string>
+		<string key="IBDocument.InterfaceBuilderVersion">7706</string>
+		<string key="IBDocument.AppKitVersion">1348.17</string>
+		<string key="IBDocument.HIToolboxVersion">758.70</string>
 		<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
 			<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
-			<string key="NS.object.0">132</string>
-		</object>
-		<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
-			<bool key="EncodedWithXMLCoder">YES</bool>
-			<integer value="2"/>
-		</object>
-		<object class="NSArray" key="IBDocument.PluginDependencies">
-			<bool key="EncodedWithXMLCoder">YES</bool>
-			<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+			<string key="NS.object.0">7703</string>
 		</object>
-		<object class="NSMutableDictionary" key="IBDocument.Metadata">
-			<bool key="EncodedWithXMLCoder">YES</bool>
-			<object class="NSArray" key="dict.sortedKeys" id="0">
-				<bool key="EncodedWithXMLCoder">YES</bool>
-			</object>
-			<object class="NSMutableArray" key="dict.values">
-				<bool key="EncodedWithXMLCoder">YES</bool>
-			</object>
-		</object>
-		<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
-			<bool key="EncodedWithXMLCoder">YES</bool>
+		<array key="IBDocument.IntegratedClassDependencies">
+			<string>IBProxyObject</string>
+			<string>IBUIButton</string>
+			<string>IBUIImageView</string>
+			<string>IBUISlider</string>
+			<string>IBUIView</string>
+			<string>IBUIViewController</string>
+		</array>
+		<array key="IBDocument.PluginDependencies">
+			<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+		</array>
+		<dictionary class="NSMutableDictionary" key="IBDocument.Metadata"/>
+		<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
 			<object class="IBProxyObject" id="841351856">
 				<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
 				<string key="targetRuntimeIdentifier">IBIPadFramework</string>
@@ -38,10 +32,9 @@
 				<string key="targetRuntimeIdentifier">IBIPadFramework</string>
 			</object>
 			<object class="IBUIView" id="766721923">
-				<reference key="NSNextResponder"/>
-				<int key="NSvFlags">292</int>
-				<object class="NSMutableArray" key="NSSubviews">
-					<bool key="EncodedWithXMLCoder">YES</bool>
+				<nil key="NSNextResponder"/>
+				<int key="NSvFlags">256</int>
+				<array class="NSMutableArray" key="NSSubviews">
 					<object class="IBUIImageView" id="109536142">
 						<reference key="NSNextResponder" ref="766721923"/>
 						<int key="NSvFlags">274</int>
@@ -66,7 +59,7 @@
 						<string key="targetRuntimeIdentifier">IBIPadFramework</string>
 						<object class="NSCustomResource" key="IBUIImage">
 							<string key="NSClassName">NSImage</string>
-							<string key="NSResourceName">title~iphone.png</string>
+							<string key="NSResourceName">title.png</string>
 						</object>
 					</object>
 					<object class="IBUIButton" id="410546531">
@@ -79,19 +72,14 @@
 						<string key="targetRuntimeIdentifier">IBIPadFramework</string>
 						<int key="IBUIContentHorizontalAlignment">0</int>
 						<int key="IBUIContentVerticalAlignment">0</int>
-						<object class="NSFont" key="IBUIFont" id="243320520">
-							<string key="NSName">Helvetica-Bold</string>
-							<double key="NSSize">15</double>
-							<int key="NSfFlags">16</int>
+						<object class="NSColor" key="IBUINormalTitleColor">
+							<int key="NSColorSpace">1</int>
+							<bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
 						</object>
 						<object class="NSColor" key="IBUIHighlightedTitleColor" id="473179629">
 							<int key="NSColorSpace">3</int>
 							<bytes key="NSWhite">MQA</bytes>
 						</object>
-						<object class="NSColor" key="IBUINormalTitleColor">
-							<int key="NSColorSpace">1</int>
-							<bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
-						</object>
 						<object class="NSColor" key="IBUINormalTitleShadowColor" id="702849038">
 							<int key="NSColorSpace">3</int>
 							<bytes key="NSWhite">MC41AA</bytes>
@@ -100,6 +88,17 @@
 							<string key="NSClassName">NSImage</string>
 							<string key="NSResourceName">startGameButton.png</string>
 						</object>
+						<object class="IBUIFontDescription" key="IBUIFontDescription" id="654921024">
+							<string key="name">Helvetica-Bold</string>
+							<string key="family">Helvetica</string>
+							<int key="traits">2</int>
+							<double key="pointSize">15</double>
+						</object>
+						<object class="NSFont" key="IBUIFont" id="243320520">
+							<string key="NSName">Helvetica-Bold</string>
+							<double key="NSSize">15</double>
+							<int key="NSfFlags">16</int>
+						</object>
 					</object>
 					<object class="IBUIButton" id="495854712">
 						<reference key="NSNextResponder" ref="766721923"/>
@@ -110,17 +109,18 @@
 						<string key="targetRuntimeIdentifier">IBIPadFramework</string>
 						<int key="IBUIContentHorizontalAlignment">0</int>
 						<int key="IBUIContentVerticalAlignment">0</int>
-						<reference key="IBUIFont" ref="243320520"/>
-						<reference key="IBUIHighlightedTitleColor" ref="473179629"/>
 						<object class="NSColor" key="IBUINormalTitleColor">
 							<int key="NSColorSpace">1</int>
 							<bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
 						</object>
+						<reference key="IBUIHighlightedTitleColor" ref="473179629"/>
 						<reference key="IBUINormalTitleShadowColor" ref="702849038"/>
 						<object class="NSCustomResource" key="IBUINormalImage">
 							<string key="NSClassName">NSImage</string>
 							<string key="NSResourceName">backButton.png</string>
 						</object>
+						<reference key="IBUIFontDescription" ref="654921024"/>
+						<reference key="IBUIFont" ref="243320520"/>
 					</object>
 					<object class="IBUIButton" id="688316814">
 						<reference key="NSNextResponder" ref="766721923"/>
@@ -132,17 +132,18 @@
 						<string key="targetRuntimeIdentifier">IBIPadFramework</string>
 						<int key="IBUIContentHorizontalAlignment">0</int>
 						<int key="IBUIContentVerticalAlignment">0</int>
-						<reference key="IBUIFont" ref="243320520"/>
-						<reference key="IBUIHighlightedTitleColor" ref="473179629"/>
 						<object class="NSColor" key="IBUINormalTitleColor">
 							<int key="NSColorSpace">1</int>
 							<bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
 						</object>
+						<reference key="IBUIHighlightedTitleColor" ref="473179629"/>
 						<reference key="IBUINormalTitleShadowColor" ref="702849038"/>
 						<object class="NSCustomResource" key="IBUINormalImage">
 							<string key="NSClassName">NSImage</string>
 							<string key="NSResourceName">helpButton.png</string>
 						</object>
+						<reference key="IBUIFontDescription" ref="654921024"/>
+						<reference key="IBUIFont" ref="243320520"/>
 					</object>
 					<object class="IBUIView" id="123574818">
 						<reference key="NSNextResponder" ref="766721923"/>
@@ -179,27 +180,47 @@
 						<float key="IBUIValue">0.05000000074505806</float>
 						<float key="IBUIMaxValue">0.05000000074505806</float>
 					</object>
-				</object>
+				</array>
 				<string key="NSFrameSize">{1024, 768}</string>
-				<reference key="NSSuperview"/>
 				<reference key="IBUIBackgroundColor" ref="473179629"/>
 				<bool key="IBUIClipsSubviews">YES</bool>
 				<object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+					<int key="IBUIInterfaceOrientation">3</int>
 					<int key="interfaceOrientation">3</int>
 				</object>
+				<object class="IBUIScreenMetrics" key="IBUISimulatedDestinationMetrics" id="465546060">
+					<string key="IBUISimulatedSizeMetricsClass">IBUIScreenMetrics</string>
+					<string key="IBUITargetRuntime">IBIPadFramework</string>
+					<string key="IBUIDisplayName">iPad Full Screen</string>
+					<object class="NSMutableDictionary" key="IBUINormalizedOrientationToSizeMap">
+						<bool key="EncodedWithXMLCoder">YES</bool>
+						<array key="dict.sortedKeys">
+							<integer value="1"/>
+							<integer value="3"/>
+						</array>
+						<array key="dict.values">
+							<string>{768, 1024}</string>
+							<string>{1024, 768}</string>
+						</array>
+					</object>
+					<int key="IBUIType">1</int>
+				</object>
 				<string key="targetRuntimeIdentifier">IBIPadFramework</string>
 			</object>
 			<object class="IBUIViewController" id="1023023363">
 				<bool key="IBUIAutoresizesArchivedViewToFullSize">NO</bool>
 				<object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics" id="158576700">
+					<int key="IBUIInterfaceOrientation">3</int>
 					<int key="interfaceOrientation">3</int>
 				</object>
+				<reference key="IBUISimulatedDestinationMetrics" ref="465546060"/>
 				<string key="targetRuntimeIdentifier">IBIPadFramework</string>
 				<bool key="IBUIHorizontal">YES</bool>
 			</object>
 			<object class="IBUIViewController" id="487135035">
 				<bool key="IBUIAutoresizesArchivedViewToFullSize">NO</bool>
 				<reference key="IBUISimulatedOrientationMetrics" ref="158576700"/>
+				<reference key="IBUISimulatedDestinationMetrics" ref="465546060"/>
 				<string key="targetRuntimeIdentifier">IBIPadFramework</string>
 				<bool key="IBUIHorizontal">YES</bool>
 			</object>
@@ -207,13 +228,13 @@
 				<bool key="IBUIAutoresizesArchivedViewToFullSize">NO</bool>
 				<string key="IBUINibName">MapConfigViewController-iPad</string>
 				<reference key="IBUISimulatedOrientationMetrics" ref="158576700"/>
+				<reference key="IBUISimulatedDestinationMetrics" ref="465546060"/>
 				<string key="targetRuntimeIdentifier">IBIPadFramework</string>
 				<bool key="IBUIHorizontal">YES</bool>
 			</object>
-		</object>
+		</array>
 		<object class="IBObjectContainer" key="IBDocument.Objects">
-			<object class="NSMutableArray" key="connectionRecords">
-				<bool key="EncodedWithXMLCoder">YES</bool>
+			<array key="connectionRecords">
 				<object class="IBConnectionRecord">
 					<object class="IBCocoaTouchOutletConnection" key="connection">
 						<string key="label">view</string>
@@ -223,6 +244,47 @@
 					<int key="connectionID">3</int>
 				</object>
 				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">teamConfigViewController</string>
+						<reference key="source" ref="841351856"/>
+						<reference key="destination" ref="487135035"/>
+					</object>
+					<int key="connectionID">45</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">schemeWeaponConfigViewController</string>
+						<reference key="source" ref="841351856"/>
+						<reference key="destination" ref="1023023363"/>
+					</object>
+					<int key="connectionID">51</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">mapConfigViewController</string>
+						<reference key="source" ref="841351856"/>
+						<reference key="destination" ref="670598485"/>
+					</object>
+					<int key="connectionID">57</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">titleImage</string>
+						<reference key="source" ref="841351856"/>
+						<reference key="destination" ref="533754865"/>
+					</object>
+					<int key="connectionID">68</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchEventConnection" key="connection">
+						<string key="label">buttonPressed:</string>
+						<reference key="source" ref="410546531"/>
+						<reference key="destination" ref="841351856"/>
+						<int key="IBEventType">7</int>
+					</object>
+					<int key="connectionID">36</int>
+				</object>
+				<object class="IBConnectionRecord">
 					<object class="IBCocoaTouchEventConnection" key="connection">
 						<string key="label">buttonPressed:</string>
 						<reference key="source" ref="495854712"/>
@@ -234,15 +296,6 @@
 				<object class="IBConnectionRecord">
 					<object class="IBCocoaTouchEventConnection" key="connection">
 						<string key="label">buttonPressed:</string>
-						<reference key="source" ref="410546531"/>
-						<reference key="destination" ref="841351856"/>
-						<int key="IBEventType">7</int>
-					</object>
-					<int key="connectionID">36</int>
-				</object>
-				<object class="IBConnectionRecord">
-					<object class="IBCocoaTouchEventConnection" key="connection">
-						<string key="label">buttonPressed:</string>
 						<reference key="source" ref="688316814"/>
 						<reference key="destination" ref="841351856"/>
 						<int key="IBEventType">7</int>
@@ -251,14 +304,6 @@
 				</object>
 				<object class="IBConnectionRecord">
 					<object class="IBCocoaTouchOutletConnection" key="connection">
-						<string key="label">teamConfigViewController</string>
-						<reference key="source" ref="841351856"/>
-						<reference key="destination" ref="487135035"/>
-					</object>
-					<int key="connectionID">45</int>
-				</object>
-				<object class="IBConnectionRecord">
-					<object class="IBCocoaTouchOutletConnection" key="connection">
 						<string key="label">view</string>
 						<reference key="source" ref="487135035"/>
 						<reference key="destination" ref="983956256"/>
@@ -275,19 +320,11 @@
 				</object>
 				<object class="IBConnectionRecord">
 					<object class="IBCocoaTouchOutletConnection" key="connection">
-						<string key="label">schemeWeaponConfigViewController</string>
-						<reference key="source" ref="841351856"/>
-						<reference key="destination" ref="1023023363"/>
+						<string key="label">slider</string>
+						<reference key="source" ref="670598485"/>
+						<reference key="destination" ref="1000322445"/>
 					</object>
-					<int key="connectionID">51</int>
-				</object>
-				<object class="IBConnectionRecord">
-					<object class="IBCocoaTouchOutletConnection" key="connection">
-						<string key="label">mapConfigViewController</string>
-						<reference key="source" ref="841351856"/>
-						<reference key="destination" ref="670598485"/>
-					</object>
-					<int key="connectionID">57</int>
+					<int key="connectionID">69</int>
 				</object>
 				<object class="IBConnectionRecord">
 					<object class="IBCocoaTouchEventConnection" key="connection">
@@ -307,29 +344,12 @@
 					</object>
 					<int key="connectionID">67</int>
 				</object>
-				<object class="IBConnectionRecord">
-					<object class="IBCocoaTouchOutletConnection" key="connection">
-						<string key="label">titleImage</string>
-						<reference key="source" ref="841351856"/>
-						<reference key="destination" ref="533754865"/>
-					</object>
-					<int key="connectionID">68</int>
-				</object>
-				<object class="IBConnectionRecord">
-					<object class="IBCocoaTouchOutletConnection" key="connection">
-						<string key="label">slider</string>
-						<reference key="source" ref="670598485"/>
-						<reference key="destination" ref="1000322445"/>
-					</object>
-					<int key="connectionID">69</int>
-				</object>
-			</object>
+			</array>
 			<object class="IBMutableOrderedSet" key="objectRecords">
-				<object class="NSArray" key="orderedObjects">
-					<bool key="EncodedWithXMLCoder">YES</bool>
+				<array key="orderedObjects">
 					<object class="IBObjectRecord">
 						<int key="objectID">0</int>
-						<reference key="object" ref="0"/>
+						<array key="object" id="0"/>
 						<reference key="children" ref="1000"/>
 						<nil key="parent"/>
 					</object>
@@ -347,8 +367,7 @@
 					<object class="IBObjectRecord">
 						<int key="objectID">2</int>
 						<reference key="object" ref="766721923"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
+						<array class="NSMutableArray" key="children">
 							<reference ref="109536142"/>
 							<reference ref="533754865"/>
 							<reference ref="410546531"/>
@@ -357,7 +376,7 @@
 							<reference ref="123574818"/>
 							<reference ref="983956256"/>
 							<reference ref="1000322445"/>
-						</object>
+						</array>
 						<reference key="parent" ref="0"/>
 					</object>
 					<object class="IBObjectRecord">
@@ -393,17 +412,13 @@
 					<object class="IBObjectRecord">
 						<int key="objectID">44</int>
 						<reference key="object" ref="487135035"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-						</object>
+						<array class="NSMutableArray" key="children"/>
 						<reference key="parent" ref="0"/>
 					</object>
 					<object class="IBObjectRecord">
 						<int key="objectID">46</int>
 						<reference key="object" ref="983956256"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-						</object>
+						<array class="NSMutableArray" key="children"/>
 						<reference key="parent" ref="766721923"/>
 						<string key="objectName">TeamConfigViewController View</string>
 					</object>
@@ -429,650 +444,52 @@
 						<reference key="parent" ref="766721923"/>
 						<string key="objectName">Filter Slider</string>
 					</object>
-				</object>
+				</array>
 			</object>
-			<object class="NSMutableDictionary" key="flattenedProperties">
-				<bool key="EncodedWithXMLCoder">YES</bool>
-				<object class="NSArray" key="dict.sortedKeys">
-					<bool key="EncodedWithXMLCoder">YES</bool>
-					<string>-1.CustomClassName</string>
-					<string>-2.CustomClassName</string>
-					<string>2.IBEditorWindowLastContentRect</string>
-					<string>2.IBPluginDependency</string>
-					<string>30.IBPluginDependency</string>
-					<string>30.IBViewBoundsToFrameTransform</string>
-					<string>31.IBPluginDependency</string>
-					<string>31.IBViewBoundsToFrameTransform</string>
-					<string>32.IBPluginDependency</string>
-					<string>32.IBViewBoundsToFrameTransform</string>
-					<string>33.IBPluginDependency</string>
-					<string>33.IBViewBoundsToFrameTransform</string>
-					<string>34.IBPluginDependency</string>
-					<string>34.IBViewBoundsToFrameTransform</string>
-					<string>44.CustomClassName</string>
-					<string>44.IBEditorWindowLastContentRect</string>
-					<string>44.IBPluginDependency</string>
-					<string>46.IBPluginDependency</string>
-					<string>46.IBViewBoundsToFrameTransform</string>
-					<string>48.CustomClassName</string>
-					<string>48.IBEditorWindowLastContentRect</string>
-					<string>48.IBPluginDependency</string>
-					<string>49.IBPluginDependency</string>
-					<string>49.IBViewBoundsToFrameTransform</string>
-					<string>55.CustomClassName</string>
-					<string>55.IBEditorWindowLastContentRect</string>
-					<string>55.IBPluginDependency</string>
-					<string>60.CustomClassName</string>
-					<string>60.IBPluginDependency</string>
-					<string>60.IBViewBoundsToFrameTransform</string>
-				</object>
-				<object class="NSMutableArray" key="dict.values">
-					<bool key="EncodedWithXMLCoder">YES</bool>
-					<string>GameConfigViewController</string>
-					<string>UIResponder</string>
-					<string>{{252, 239}, {1024, 768}}</string>
-					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
-					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
-					<object class="NSAffineTransform">
-						<bytes key="NSTransformStruct">P4AAAL+AAABAoAAAxLrgAA</bytes>
-					</object>
-					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
-					<object class="NSAffineTransform">
-						<bytes key="NSTransformStruct">P4AAAL+AAABDtQAAxGNAAA</bytes>
-					</object>
-					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
-					<object class="NSAffineTransform">
-						<bytes key="NSTransformStruct">P4AAAL+AAABD3wAAxLqgAA</bytes>
-					</object>
-					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
-					<object class="NSAffineTransform">
-						<bytes key="NSTransformStruct">P4AAAL+AAABByAAAxLmAAA</bytes>
-					</object>
-					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
-					<object class="NSAffineTransform">
-						<bytes key="NSTransformStruct">P4AAAL+AAABEbEAAxLmAAA</bytes>
-					</object>
-					<string>TeamConfigViewController</string>
-					<string>{{63, 355}, {1024, 768}}</string>
-					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
-					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
-					<object class="NSAffineTransform">
-						<bytes key="NSTransformStruct">AUOogABDOwAAA</bytes>
-					</object>
-					<string>SchemeWeaponConfigViewController</string>
-					<string>{{84, 388}, {1024, 768}}</string>
-					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
-					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
-					<object class="NSAffineTransform">
-						<bytes key="NSTransformStruct">P4AAAL+AAAAAAAAAxHqAAA</bytes>
-					</object>
-					<string>MapConfigViewController</string>
-					<string>{{126, 377}, {1024, 768}}</string>
-					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
-					<string>MNEValueTrackingSlider</string>
-					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
-					<object class="NSAffineTransform">
-						<bytes key="NSTransformStruct">AUNRAABEMoAAA</bytes>
-					</object>
-				</object>
-			</object>
-			<object class="NSMutableDictionary" key="unlocalizedProperties">
-				<bool key="EncodedWithXMLCoder">YES</bool>
-				<reference key="dict.sortedKeys" ref="0"/>
-				<object class="NSMutableArray" key="dict.values">
-					<bool key="EncodedWithXMLCoder">YES</bool>
-				</object>
-			</object>
+			<dictionary class="NSMutableDictionary" key="flattenedProperties">
+				<string key="-1.CustomClassName">GameConfigViewController</string>
+				<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="-2.CustomClassName">UIResponder</string>
+				<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="30.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="31.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="32.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="33.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="34.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="44.CustomClassName">TeamConfigViewController</string>
+				<string key="44.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="46.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="48.CustomClassName">SchemeWeaponConfigViewController</string>
+				<string key="48.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="49.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="55.CustomClassName">MapConfigViewController</string>
+				<string key="55.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="60.CustomClassName">MNEValueTrackingSlider</string>
+				<string key="60.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+			</dictionary>
+			<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
 			<nil key="activeLocalization"/>
-			<object class="NSMutableDictionary" key="localizations">
-				<bool key="EncodedWithXMLCoder">YES</bool>
-				<reference key="dict.sortedKeys" ref="0"/>
-				<object class="NSMutableArray" key="dict.values">
-					<bool key="EncodedWithXMLCoder">YES</bool>
-				</object>
-			</object>
+			<dictionary class="NSMutableDictionary" key="localizations"/>
 			<nil key="sourceID"/>
 			<int key="maxID">69</int>
 		</object>
-		<object class="IBClassDescriber" key="IBDocument.Classes">
-			<object class="NSMutableArray" key="referencedPartialClassDescriptions">
-				<bool key="EncodedWithXMLCoder">YES</bool>
-				<object class="IBPartialClassDescription">
-					<string key="className">GameConfigViewController</string>
-					<string key="superclassName">UIViewController</string>
-					<object class="NSMutableDictionary" key="actions">
-						<bool key="EncodedWithXMLCoder">YES</bool>
-						<object class="NSArray" key="dict.sortedKeys">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<string>buttonPressed:</string>
-							<string>segmentPressed:</string>
-						</object>
-						<object class="NSMutableArray" key="dict.values">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<string>id</string>
-							<string>id</string>
-						</object>
-					</object>
-					<object class="NSMutableDictionary" key="actionInfosByName">
-						<bool key="EncodedWithXMLCoder">YES</bool>
-						<object class="NSArray" key="dict.sortedKeys">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<string>buttonPressed:</string>
-							<string>segmentPressed:</string>
-						</object>
-						<object class="NSMutableArray" key="dict.values">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<object class="IBActionInfo">
-								<string key="name">buttonPressed:</string>
-								<string key="candidateClassName">id</string>
-							</object>
-							<object class="IBActionInfo">
-								<string key="name">segmentPressed:</string>
-								<string key="candidateClassName">id</string>
-							</object>
-						</object>
-					</object>
-					<object class="NSMutableDictionary" key="outlets">
-						<bool key="EncodedWithXMLCoder">YES</bool>
-						<object class="NSArray" key="dict.sortedKeys">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<string>mapConfigViewController</string>
-							<string>schemeWeaponConfigViewController</string>
-							<string>teamConfigViewController</string>
-							<string>titleImage</string>
-						</object>
-						<object class="NSMutableArray" key="dict.values">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<string>MapConfigViewController</string>
-							<string>SchemeWeaponConfigViewController</string>
-							<string>TeamConfigViewController</string>
-							<string>UIImageView</string>
-						</object>
-					</object>