update with default webgl
authorkoda
Sun, 09 Jun 2013 12:22:53 +0200
branchwebgl
changeset 9160 fc46e75f6b72
parent 9136 78f087fd3e5b (diff)
parent 9159 3e9d4bbc4053 (current diff)
child 9162 2c6ad606f4fb
update with default
CMakeLists.txt
QTfrontend/ui/page/pagevideos.cpp
QTfrontend/ui/qaspectratiolayout.cpp
QTfrontend/ui/qaspectratiolayout.h
QTfrontend/ui/widget/about.cpp
gameServer/Actions.hs
hedgewars/CMakeLists.txt
hedgewars/GSHandlers.inc
hedgewars/uAIAmmoTests.pas
hedgewars/uAIMisc.pas
hedgewars/uChat.pas
hedgewars/uGearsHedgehog.pas
hedgewars/uGearsUtils.pas
hedgewars/uTeams.pas
misc/libphysfs/CMakeLists.txt
--- a/.hgignore	Sun Jun 09 12:20:19 2013 +0200
+++ b/.hgignore	Sun Jun 09 12:22:53 2013 +0200
@@ -43,6 +43,8 @@
 glob:*.orig
 glob:*.bak
 glob:*.rej
+glob:project_files/hwc/*.c
+glob:project_files/hwc/*.h
 glob:project_files/Android-build/SDL-android-project/jni/**
 glob:project_files/Android-build/SDL-android-project/obj
 glob:project_files/Android-build/SDL-android-project/libs/armeabi*
--- a/CMakeLists.txt	Sun Jun 09 12:20:19 2013 +0200
+++ b/CMakeLists.txt	Sun Jun 09 12:22:53 2013 +0200
@@ -19,7 +19,7 @@
 #set this to ON when 2.1.0 becomes more widespread (and only for linux)
 option(PHYSFS_SYSTEM "Use system physfs (off)" OFF)
 
-option(BUILD_ENGINE_LIBRARY "Enable hwengine library (off)" OFF)
+option(LIBENGINE "Enable hwengine library (off)" OFF)
 option(ANDROID "Enable Android build (off)" OFF)
 
 if(UNIX AND NOT APPLE)
@@ -28,6 +28,10 @@
     option(NOAUTOUPDATE "Disable OS X Sparkle update checking" OFF)
 endif()
 
+option(WEBGL "Enable WebGL build (implies NOPASCAL) [default: off]" OFF)
+option(NOPASCAL "Compile hwengine as native C [default: off]" ${WEBGL})
+option(GL2 "Enable OpenGL 2 rendering [default: off]" OFF)
+
 set(FPFLAGS "" CACHE STRING "Additional Freepascal flags")
 set(GHFLAGS "" CACHE STRING "Additional Haskell flags")
 if(UNIX AND NOT APPLE)
@@ -42,9 +46,21 @@
 set(HEDGEWARS_PROTO_VER 46)
 set(HEDGEWARS_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
 include(${CMAKE_MODULE_PATH}/revinfo.cmake)
+set(required_clang_version 3.0)
 
 message(STATUS "Building ${HEDGEWARS_VERSION}-r${HEDGEWARS_REVISION} (${HEDGEWARS_HASH})")
 
+if (${NOPASCAL})
+    find_package(Clang)
+    # Check LLVM/Clang version
+	if (CLANG_VERSION VERSION_LESS required_clang_version)
+		message(FATAL_ERROR "LLVM/Clang compiler required version is ${required_clang_version} but version ${CLANG_VERSION} was found!")
+	else()
+		message(STATUS "Found CLANG: ${CLANG_EXECUTABLE} (version ${CLANG_VERSION})")
+	endif()
+endif(${NOPASCAL})
+
+
 
 #where to build libs and bins
 set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
@@ -163,12 +179,40 @@
 
 include(${CMAKE_MODULE_PATH}/utils.cmake)
 
+#Haskell compiler discovery (for server and engine in c)
+if((NOT NOSERVER) OR NOPASCAL)
+    if(GHC)
+        set(ghc_executable ${GHC})
+    else()
+        find_program(ghc_executable ghc)
+    endif()
+
+    if(ghc_executable)
+        exec_program(${ghc_executable} ARGS "-V" OUTPUT_VARIABLE ghc_version_long)
+        string(REGEX REPLACE ".*([0-9]+\\.[0-9]+\\.[0-9]+)" "\\1" ghc_version "${ghc_version_long}")
+        message(STATUS "Found GHC: ${ghc_executable} (version ${ghc_version})")
+    else()
+        message(STATUS "Could NOT find GHC, needed by gameServer and pas2c")
+    endif()
+endif()
+
+
+#check gameServer
+if((ghc_executable) AND (NOT NOSERVER) AND (NOT WEBGL))
+    set(HAVE_NETSERVER true)
+    add_subdirectory(gameServer)
+else()
+    message(STATUS "Skipping gameServer target")
+    set(HAVE_NETSERVER false)
+endif()
+
+
 #lua discovery
 find_package(Lua)
-if(LUA_FOUND)
+if(LUA_FOUND AND (NOT WEBGL))
     message(STATUS "Found LUA: ${LUA_DEFAULT}")
 else()
-    message(STATUS "LUA will be provided by the bundled sources")
+    message(STATUS "Using internal LUA library")
     add_subdirectory(misc/liblua)
     #linking with liblua.a requires system readline
     list(APPEND pascal_flags "-k${EXECUTABLE_OUTPUT_PATH}/lib${LUA_LIBRARY}.a" "-k-lreadline")
@@ -215,28 +259,33 @@
 #physfs helper library
 add_subdirectory(misc/libphyslayer)
 
-#server
-if(NOT NOSERVER)
-    add_subdirectory(gameServer)
+if(NOPASCAL)
+    if (NOT ghc_executable)
+        message(FATAL_ERROR "A Haskell compiler is required to build engine in C")
+    endif()
+    add_subdirectory(hedgewars/sdlmain_osx)
+    #pascal to c converter
+    add_subdirectory(tools/pas2c)
+    add_subdirectory(project_files/hwc)
+else()
+    #main pascal engine
+    add_subdirectory(hedgewars)
 endif()
 
-#main engine
-add_subdirectory(hedgewars)
-
-#Android related build scripts
-if(ANDROID)
-    #run cmake -DANDROID=1 to enable this
-    add_subdirectory(project_files/Android-build)
-endif()
-
-#TODO: when ANDROID, BUILD_ENGINE_LIBRARY should be set
-if(NOT ANDROID)
-    add_subdirectory(bin)
-    add_subdirectory(QTfrontend)
-    add_subdirectory(share)
-    add_subdirectory(tools)
-endif()
-
+if(WEBGL)
+    #WEBGL deps
+else(WEBGL)
+    #Android related build scripts
+    #TODO: when ANDROID, LIBENGINE should be set
+    if(ANDROID)
+        add_subdirectory(project_files/Android-build)
+    else(ANDROID)
+        add_subdirectory(bin)
+        add_subdirectory(QTfrontend)
+        add_subdirectory(share)
+        add_subdirectory(tools)
+    endif(ANDROID)
+endif(WEBGL)
 
 include(${CMAKE_MODULE_PATH}/cpackvars.cmake)
 
--- a/QTfrontend/CMakeLists.txt	Sun Jun 09 12:20:19 2013 +0200
+++ b/QTfrontend/CMakeLists.txt	Sun Jun 09 12:22:53 2013 +0200
@@ -181,6 +181,11 @@
 if(CMAKE_BUILD_TYPE MATCHES "RELEASE")
     set(console_access "WIN32")
 endif(CMAKE_BUILD_TYPE MATCHES "RELEASE")
+if(${LIBENGINE})
+    add_definitions(-DHWLIBRARY)
+    set(HW_LINK_LIBS hwengine ${HW_LINK_LIBS})
+    link_directories(${EXECUTABLE_OUTPUT_PATH})
+endif()
 
 add_executable(hedgewars ${console_access}
     ${hwfr_src}
@@ -189,7 +194,7 @@
     ${hwfr_rez_src}
     )
 
-if((UNIX AND NOT APPLE) AND ${BUILD_ENGINE_LIBRARY})
+if((UNIX AND NOT APPLE) AND ${LIBENGINE})
     set_target_properties(hedgewars PROPERTIES LINK_FLAGS "-Wl,-rpath,${CMAKE_INSTALL_PREFIX}/${target_library_install_dir}")
 endif()
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake_modules/FindClang.cmake	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,21 @@
+# Load LLVM/Clang
+if (CLANG)
+    set(CLANG_EXECUTABLE ${CLANG})
+else()
+    find_program(CLANG_EXECUTABLE
+        NAMES clang-mp-3.3 clang-mp-3.2 clang-mp-3.1 clang-mp-3.0 clang
+        PATHS /opt/local/bin /usr/local/bin /usr/bin)
+endif()
+
+# Check LLVM/Clang version
+if (CLANG_EXECUTABLE)
+    exec_program(${CLANG_EXECUTABLE} ARGS "-v" OUTPUT_VARIABLE CLANG_VERSION_FULL)
+
+    string(REGEX MATCH "[0-9]+\\.[0-9]+" CLANG_VERSION_LONG "${CLANG_VERSION_FULL}")
+    string(REGEX REPLACE "([0-9]+\\.[0-9]+)" "\\1" CLANG_VERSION "${CLANG_VERSION_LONG}")
+else()
+    message(FATAL_ERROR "No LLVM/Clang compiler found (required for engine_c target)")
+endif()
+
+set(CMAKE_C_COMPILER ${CLANG_EXECUTABLE})
+set(CMAKE_CXX_COMPILER ${CLANG_EXECUTABLE})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake_modules/FindGLEW.cmake	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,65 @@
+#
+# Try to find GLEW library and include path.
+# Once done this will define
+#
+# GLEW_FOUND
+# GLEW_INCLUDE_DIRS
+# GLEW_LIBRARY
+# 
+
+if (GLEW_LIBRARY AND GLEW_INCLUDE_DIRS)
+  # in cache already
+  set(GLEW_FOUND TRUE)
+else (GLEW_LIBRARY AND GLEW_INCLUDE_DIRS)
+
+    IF (WIN32)
+        FIND_PATH( GLEW_INCLUDE_DIRS GL/glew.h
+            $ENV{PROGRAMFILES}/GLEW/include
+            ${PROJECT_SOURCE_DIR}/src/nvgl/glew/include
+            DOC "The directory where GL/glew.h resides")
+        FIND_LIBRARY( GLEW_LIBRARY
+            NAMES glew GLEW glew32 glew32s
+            PATHS
+            $ENV{PROGRAMFILES}/GLEW/lib
+            ${PROJECT_SOURCE_DIR}/src/nvgl/glew/bin
+            ${PROJECT_SOURCE_DIR}/src/nvgl/glew/lib
+        DOC "The GLEW library")
+    ELSE (WIN32)
+        FIND_PATH( GLEW_INCLUDE_DIRS GL/glew.h
+            /usr/include
+            /usr/local/include
+            /sw/include
+            /opt/local/include
+            DOC "The directory where GL/glew.h resides")
+        FIND_LIBRARY( GLEW_LIBRARY
+            NAMES GLEW glew
+            PATHS
+            /usr/lib64
+            /usr/lib
+            /usr/local/lib64
+            /usr/local/lib
+            /sw/lib
+            /opt/local/lib
+            DOC "The GLEW library")
+    ENDIF (WIN32)
+
+    IF (GLEW_LIBRARY AND GLEW_INCLUDE_DIRS)
+        SET( GLEW_FOUND 1 CACHE STRING "Set to 1 if GLEW is found, 0 otherwise")
+    ELSE (GLEW_LIBRARY AND GLEW_INCLUDE_DIRS)
+        SET( GLEW_FOUND 0 CACHE STRING "Set to 1 if GLEW is found, 0 otherwise")
+    ENDIF (GLEW_LIBRARY AND GLEW_INCLUDE_DIRS)
+
+endif(GLEW_LIBRARY AND GLEW_INCLUDE_DIRS)
+
+if (GLEW_FOUND)
+    if (NOT GLEW_FIND_QUIETLY)
+        message(STATUS "Found GLEW: ${GLEW_LIBRARY}, ${GLEW_INCLUDE_DIRS}")
+    endif (NOT GLEW_FIND_QUIETLY)
+else (GLEW_FOUND)
+    if (GLEW_FIND_REQUIRED)
+        message(FATAL_ERROR "Could NOT find GLEW")
+    endif (GLEW_FIND_REQUIRED)
+endif (GLEW_FOUND)
+
+#MARK_AS_ADVANCED( GLEW_FOUND )
+
--- a/gameServer/Actions.hs	Sun Jun 09 12:20:19 2013 +0200
+++ b/gameServer/Actions.hs	Sun Jun 09 12:22:53 2013 +0200
@@ -494,7 +494,7 @@
 
 processAction (BanNick n seconds reason) = do
     currentTime <- io getCurrentTime
-    let msg = 
+    let msg =
             if seconds > 60 * 60 * 24 * 365 then
                 B.concat ["Permanent ban (", reason, ")"]
                 else
--- a/gameServer/CMakeLists.txt	Sun Jun 09 12:20:19 2013 +0200
+++ b/gameServer/CMakeLists.txt	Sun Jun 09 12:22:53 2013 +0200
@@ -26,11 +26,11 @@
     hedgewars-server.hs
     )
 
-set(hwserv_main ${hedgewars_SOURCE_DIR}/gameServer/hedgewars-server.hs)
+set(hwserv_main ${CMAKE_SOURCE_DIR}/gameServer/hedgewars-server.hs)
 
 set(ghc_flags
     --make ${hwserv_main}
-    -i${hedgewars_SOURCE_DIR}/gameServer
+    -i${CMAKE_CURRENT_SOURCE_DIR}
     -o ${EXECUTABLE_OUTPUT_PATH}/hedgewars-server${CMAKE_EXECUTABLE_SUFFIX}
     -odir ${CMAKE_CURRENT_BINARY_DIR}
     -hidir ${CMAKE_CURRENT_BINARY_DIR}
--- a/gameServer/hedgewars-server.cabal	Sun Jun 09 12:20:19 2013 +0200
+++ b/gameServer/hedgewars-server.cabal	Sun Jun 09 12:22:53 2013 +0200
@@ -16,7 +16,6 @@
 
   Build-depends:
     base >= 4.3,
-    unix,
     containers,
     vector,
     bytestring,
--- a/hedgewars/ArgParsers.inc	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/ArgParsers.inc	Sun Jun 09 12:22:53 2013 +0200
@@ -93,7 +93,7 @@
         end
 end;
 
-function parseNick(nick: String): String;
+function parseNick(nick: shortstring): shortstring;
 begin
     if isInternal then
         parseNick:= DecodeBase64(nick)
@@ -140,18 +140,22 @@
 {$ENDIF}
 end;
 
-function getLongIntParameter(str:String; var paramIndex:LongInt; var wrongParameter:Boolean): LongInt;
+function getLongIntParameter(str:shortstring; var paramIndex:LongInt; var wrongParameter:Boolean): LongInt;
 var tmpInt, c: LongInt;
 begin
     inc(paramIndex);
+{$IFDEF PAS2C}
+    val(str, tmpInt);
+{$ELSE}
     val(str, tmpInt, c);
     wrongParameter:= c <> 0;
     if wrongParameter then
         WriteLn(stderr, 'ERROR: '+ParamStr(paramIndex-1)+' expects a number, you passed "'+str+'"');
+{$ENDIF}
     getLongIntParameter:= tmpInt;
 end;
 
-function getStringParameter(str:String; var paramIndex:LongInt; var wrongParameter:Boolean): String;
+function getStringParameter(str:shortstring; var paramIndex:LongInt; var wrongParameter:Boolean): shortstring;
 begin
     inc(paramIndex);
     wrongParameter:= (str='') or (Copy(str,1,2) = '--');
@@ -160,15 +164,14 @@
     getStringParameter:= str;
 end;
 
-
-procedure parseClassicParameter(cmdArray: Array of String; size:LongInt; var paramIndex:LongInt); Forward;
+procedure parseClassicParameter(cmdarray: array of shortstring; size:LongInt; var paramIndex:LongInt); forward;
 
-function parseParameter(cmd:String; arg:String; var paramIndex:LongInt): Boolean;
-const videoArray: Array [1..5] of String = ('--fullscreen-width','--fullscreen-height', '--width', '--height', '--depth');
-      audioArray: Array [1..3] of String = ('--volume','--nomusic','--nosound');
-      otherArray: Array [1..3] of String = ('--locale','--fullscreen','--showfps');
-      mediaArray: Array [1..10] of String = ('--fullscreen-width', '--fullscreen-height', '--width', '--height', '--depth', '--volume','--nomusic','--nosound','--locale','--fullscreen');
-      allArray: Array [1..14] of String = ('--fullscreen-width','--fullscreen-height', '--width', '--height', '--depth','--volume','--nomusic','--nosound','--locale','--fullscreen','--showfps','--altdmg','--frame-interval','--low-quality');
+function parseParameter(cmd:shortstring; arg:shortstring; var paramIndex:LongInt): Boolean;
+const videoarray: array [0..4] of shortstring = ('--fullscreen-width','--fullscreen-height', '--width', '--height', '--depth');
+      audioarray: array [0..2] of shortstring = ('--volume','--nomusic','--nosound');
+      otherarray: array [0..2] of shortstring = ('--locale','--fullscreen','--showfps');
+      mediaarray: array [0..9] of shortstring = ('--fullscreen-width', '--fullscreen-height', '--width', '--height', '--depth', '--volume','--nomusic','--nosound','--locale','--fullscreen');
+      allarray: array [0..13] of shortstring = ('--fullscreen-width','--fullscreen-height', '--width', '--height', '--depth','--volume','--nomusic','--nosound','--locale','--fullscreen','--showfps','--altdmg','--frame-interval','--low-quality');
       reallyAll: array[0..30] of shortstring = (
                 '--prefix', '--user-prefix', '--locale', '--fullscreen-width', '--fullscreen-height', '--width',
                 '--height', '--frame-interval', '--volume','--nomusic', '--nosound',
@@ -206,11 +209,11 @@
         {--nick}                17 : UserNick          := parseNick( getStringParameter(arg, paramIndex, parseParameter) );
         {deprecated options}
         {--depth}               18 : setDepth(paramIndex);
-        {--set-video}           19 : parseClassicParameter(videoArray,5,paramIndex);
-        {--set-audio}           20 : parseClassicParameter(audioArray,3,paramIndex);
-        {--set-other}           21 : parseClassicParameter(otherArray,3,paramIndex);
-        {--set-multimedia}      22 : parseClassicParameter(mediaArray,10,paramIndex);
-        {--set-everything}      23 : parseClassicParameter(allArray,14,paramIndex);
+        {--set-video}           19 : parseClassicParameter(videoarray,5,paramIndex);
+        {--set-audio}           20 : parseClassicParameter(audioarray,3,paramIndex);
+        {--set-other}           21 : parseClassicParameter(otherarray,3,paramIndex);
+        {--set-multimedia}      22 : parseClassicParameter(mediaarray,10,paramIndex);
+        {--set-everything}      23 : parseClassicParameter(allarray,14,paramIndex);
         {"internal" options}
         {--internal}            24 : {$IFDEF HWLIBRARY}isInternal:= true{$ENDIF};
         {--port}                25 : setIpcPort( getLongIntParameter(arg, paramIndex, parseParameter), parseParameter );
@@ -234,10 +237,10 @@
     end;
 end;
 
-procedure parseClassicParameter(cmdArray: Array of String; size:LongInt; var paramIndex:LongInt);
+procedure parseClassicParameter(cmdarray: array of shortstring; size:LongInt; var paramIndex:LongInt);
 var index, tmpInt: LongInt;
     isBool, isValid: Boolean;
-    cmd, arg, newSyntax: String;
+    cmd, arg, newSyntax: shortstring;
 begin
     WriteLn(stdout, 'WARNING: you are using a deprecated command, which could be removed in a future version!');
     WriteLn(stdout, '         Consider updating to the latest syntax, which is much more flexible!');
@@ -250,7 +253,7 @@
         begin
         newSyntax:= '';
         inc(paramIndex);
-        cmd:= cmdArray[index];
+        cmd:= cmdarray[index];
         arg:= ParamStr(paramIndex);
         isValid:= (cmd<>'--depth');
 
@@ -264,9 +267,9 @@
         if isValid then
             begin
             parseParameter(cmd, arg, tmpInt);
-            newSyntax := newSyntax + cmd + ' ';
+            newSyntax:= newSyntax + cmd + ' ';
             if not isBool then
-                newSyntax := newSyntax + arg + ' ';
+                newSyntax:= newSyntax + arg + ' ';
             end;
         inc(index);
         end;
@@ -317,7 +320,7 @@
 begin
     isInternal:= (ParamStr(1) = '--internal');
 
-    UserPathPrefix := '.';
+    UserPathPrefix := _S'.';
     PathPrefix     := cDefaultPathPrefix;
     recordFileName := '';
     parseCommandLine();
--- a/hedgewars/CMakeLists.txt	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/CMakeLists.txt	Sun Jun 09 12:22:53 2013 +0200
@@ -20,7 +20,7 @@
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.inc.in ${CMAKE_CURRENT_BINARY_DIR}/config.inc)
 
 #SOURCE AND PROGRAMS SECTION
-if(${BUILD_ENGINE_LIBRARY})
+if(${LIBENGINE})
     set(engine_output_name "${CMAKE_SHARED_LIBRARY_PREFIX}hwengine${CMAKE_SHARED_LIBRARY_SUFFIX}")
     set(hwengine_project hwLibrary.pas)
 else()
@@ -74,6 +74,7 @@
     uLandTemplates.pas
     uLandTexture.pas
     uLocale.pas
+    uMatrix.pas
     uMisc.pas
     uPhysFSLayer.pas
     uRandom.pas
@@ -101,7 +102,7 @@
     ${CMAKE_CURRENT_BINARY_DIR}/config.inc
     )
 
-if(${BUILD_ENGINE_LIBRARY})
+if(${LIBENGINE})
     message("*** Engine will be built as library (experimental) ***")
     list(APPEND pascal_flags "-dHWLIBRARY")
 
@@ -115,12 +116,17 @@
         list(APPEND pascal_flags "-k-no_order_inits")
     endif()
     set(destination_dir ${target_library_install_dir})
-else(${BUILD_ENGINE_LIBRARY})
+else(${LIBENGINE})
     set(destination_dir ${target_binary_install_dir})
-endif(${BUILD_ENGINE_LIBRARY})
+endif(${LIBENGINE})
 
 
 include(${CMAKE_MODULE_PATH}/utils.cmake)
+#opengl 2
+IF(${GL2})
+    set(pascal_flags "-dGL2" ${pascal_flags})
+    message(STATUS "Building using OpenGL 2")
+ENDIF(${GL2})
 
 find_package_or_fail(FreePascal)
 
@@ -141,23 +147,9 @@
     endif()
 
     #on OSX we need to provide the SDL_main() function when building as executable
-    if(NOT ${BUILD_ENGINE_LIBRARY})
-        #let's look for the installed sdlmain file; if it is not found, let's build our own
-        find_package(SDL REQUIRED)
-        #remove the ";-framework Cocoa" from the SDL_LIBRARY variable
-        string(REGEX REPLACE "(.*);-.*" "\\1" sdl_library_only "${SDL_LIBRARY}")
-        #find libsdmain.a
-        find_file(SDLMAIN_LIB libSDLMain.a PATHS ${sdl_library_only}/Resources/)
-
-        if(SDLMAIN_LIB MATCHES "SDLMAIN_LIB-NOTFOUND")
-            include_directories(${SDL_INCLUDE_DIR})
-            add_library (SDLmain STATIC SDLMain.m)
-            #add a dependency to the hwengine target
-            list(APPEND engine_sources SDLmain)
-            set(SDLMAIN_LIB "${LIBRARY_OUTPUT_PATH}/libSDLmain.a")
-        endif()
-
-        list(APPEND pascal_flags "-k${SDLMAIN_LIB}")
+    if(NOT ${LIBENGINE})
+        add_subdirectory(sdlmain_osx)
+        list(APPEND pascal_flags "-k${LIBRARY_OUTPUT_PATH}/libSDLmain.a")
     endif()
 
     #when you have multiple ld installation make sure you get the one bundled with the compiler
@@ -195,11 +187,12 @@
     list(APPEND pascal_flags "-dUSE_VIDEO_RECORDING")
     if(WIN32)
         # there are some problems with linking our avwrapper as static lib, so link it as shared
-        add_library(avwrapper SHARED avwrapper.c)
+        add_library(avwrapper SHARED videorec/avwrapper.c)
         target_link_libraries(avwrapper ${FFMPEG_LIBRARIES})
         install(PROGRAMS "${EXECUTABLE_OUTPUT_PATH}/${CMAKE_SHARED_LIBRARY_PREFIX}avwrapper${CMAKE_SHARED_LIBRARY_SUFFIX}" DESTINATION ${target_library_install_dir})
+        list(APPEND pascal_flags "-dUSE_VIDEO_RECORDING")
     else()
-        add_library(avwrapper STATIC avwrapper.c)
+        add_library(avwrapper STATIC videorec/avwrapper.c)
     endif()
 endif()
 
@@ -260,6 +253,10 @@
     add_dependencies(hwengine avwrapper)
 endif()
 
+if(APPLE)
+    add_dependencies(hwengine SDLmain)
+endif(APPLE)
+
 #this command is a workaround to some inlining issues present in older FreePascal versions and fixed in 2.6
 if((FREEPASCAL_VERSION VERSION_LESS "2.6") AND (NOT ${FFMPEG_FOUND}))
     add_dependencies(hwengine ENGINECLEAN)
--- a/hedgewars/GSHandlers.inc	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/GSHandlers.inc	Sun Jun 09 12:22:53 2013 +0200
@@ -151,13 +151,13 @@
     Gear^.Y := Gear^.Y + cDrownSpeed;
     Gear^.X := Gear^.X + Gear^.dX * cDrownSpeed;
     // Create some bubbles (0.5% might be better but causes too few bubbles sometimes)
-    if ((not SuddenDeathDmg and (WaterOpacity < $FF))
+    if (((not SuddenDeathDmg) and (WaterOpacity < $FF))
     or (SuddenDeathDmg and (SDWaterOpacity < $FF))) and ((GameTicks and $1F) = 0) then
         if (Gear^.Kind = gtHedgehog) and (Random(4) = 0) then
             AddVisualGear(hwRound(Gear^.X) - Gear^.Radius, hwRound(Gear^.Y) - Gear^.Radius, vgtBubble)
     else if Random(12) = 0 then
              AddVisualGear(hwRound(Gear^.X) - Gear^.Radius, hwRound(Gear^.Y) - Gear^.Radius, vgtBubble);
-    if (not SuddenDeathDmg and (WaterOpacity > $FE))
+    if ((not SuddenDeathDmg) and (WaterOpacity > $FE))
     or (SuddenDeathDmg and (SDWaterOpacity > $FE))
     or (hwRound(Gear^.Y) > Gear^.Radius + cWaterLine + cVisibleWater) then
         DeleteGear(Gear);
@@ -173,17 +173,23 @@
     land: word;
 begin
     // clip velocity at 2 - over 1 per pixel, but really shouldn't cause many actual problems.
+{$IFNDEF WEBGL}
     if Gear^.dX.Round > 2 then
         Gear^.dX.QWordValue:= 8589934592;
     if Gear^.dY.Round > 2 then
         Gear^.dY.QWordValue:= 8589934592;
-
-    if (Gear^.State and gstSubmersible <> 0) and (hwRound(Gear^.Y) > cWaterLine) then
-        begin
-        Gear^.dX:= Gear^.dX * _0_999;
-        Gear^.dY:= Gear^.dY * _0_999
+{$ELSE}
+    if Gear^.dX.Round > 2 then
+        begin
+        Gear^.dX.Round:= 2;
+        Gear^.dX.Frac:= 0
         end;
-
+    if Gear^.dY.QWordValue > 2 then
+        begin
+        Gear^.dY.Round:= 2;
+        Gear^.dY.Frac:= 0
+        end;
+{$ENDIF}
     Gear^.State := Gear^.State and (not gstCollision);
     collV := 0;
     collH := 0;
@@ -255,7 +261,7 @@
         Gear^.dX := tdY*Gear^.Elasticity*Gear^.Friction;
         Gear^.dY := tdX*Gear^.Elasticity;
         //*Gear^.Friction;
-        Gear^.dY.isNegative := not tdY.isNegative;
+        Gear^.dY.isNegative := (not tdY.isNegative);
         isFalling := false;
         Gear^.AdvBounce := 10;
         end;
@@ -750,7 +756,7 @@
         if TestCollisionY(Gear, -1) then
             Gear^.dY := _0;
 
-    if not Gear^.dY.isNegative then
+    if (not Gear^.dY.isNegative) then
         if TestCollisionY(Gear, 1) then
         begin
             Gear^.dY := - Gear^.dY * Gear^.Elasticity;
@@ -1007,7 +1013,8 @@
 
 procedure doStepBulletWork(Gear: PGear);
 var
-    i, x, y: LongWord;
+    i: LongInt;
+    x, y: LongWord;
     oX, oY: hwFloat;
     VGear: PVisualGear;
 begin
@@ -1025,7 +1032,7 @@
         if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] <> 0) then
             inc(Gear^.Damage);
         // let's interrupt before a collision to give portals a chance to catch the bullet
-        if (Gear^.Damage = 1) and (Gear^.Tag = 0) and not(CheckLandValue(x, y, lfLandMask)) then
+        if (Gear^.Damage = 1) and (Gear^.Tag = 0) and (not(CheckLandValue(x, y, lfLandMask))) then
             begin
             Gear^.Tag := 1;
             Gear^.Damage := 0;
@@ -1052,7 +1059,7 @@
         dec(Gear^.Health, Gear^.Damage);
         Gear^.Damage := 0
         end;
-    if ((Gear^.State and gstDrowning) <> 0) and (Gear^.Damage < Gear^.Health) and ((not SuddenDeathDmg and (WaterOpacity < $FF)) or (SuddenDeathDmg and (SDWaterOpacity < $FF))) then
+    if ((Gear^.State and gstDrowning) <> 0) and (Gear^.Damage < Gear^.Health) and (((not SuddenDeathDmg) and (WaterOpacity < $FF)) or (SuddenDeathDmg and (SDWaterOpacity < $FF))) then
         begin
         for i:=(Gear^.Health - Gear^.Damage) * 4 downto 0 do
             begin
@@ -1237,7 +1244,7 @@
             Gear^.X := Gear^.X + Gear^.dX;
             Gear^.Y := Gear^.Y + _1_9;
             end;
-        SetAllHHToActive;
+        SetAllHHToActive(true);
         end;
     if TestCollisionYwithGear(Gear, 1) <> 0 then
         begin
@@ -1634,7 +1641,7 @@
     if Gear^.dX.QWordValue = 0 then AddGearCI(Gear)
     end; *)
 
-    if not Gear^.dY.isNegative and (Gear^.dY < _0_001) and (TestCollisionYwithGear(Gear, 1) <> 0) then
+    if (not Gear^.dY.isNegative) and (Gear^.dY < _0_001) and (TestCollisionYwithGear(Gear, 1) <> 0) then
         Gear^.dY := _0;
     if hwAbs(Gear^.dX) < _0_001 then
         Gear^.dX := _0;
@@ -1894,7 +1901,7 @@
     tdX,tdY: HWFloat;
 begin
     sticky:= (Gear^.State and gsttmpFlag) <> 0;
-    if not sticky then AllInactive := false;
+    if (not sticky) then AllInactive := false;
 
     if TestCollisionYwithGear(Gear, 1) = 0 then
         begin
@@ -1961,7 +1968,7 @@
             gX := hwRound(Gear^.X);
             gY := hwRound(Gear^.Y);
             // Standard fire
-            if not sticky then
+            if (not sticky) then
                 begin
                 if ((GameTicks and $1) = 0) then
                     begin
@@ -2011,7 +2018,7 @@
         begin
         gX := hwRound(Gear^.X);
         gY := hwRound(Gear^.Y);
-        if not sticky then
+        if (not sticky) then
             begin
             if ((GameTicks and $3) = 0) and (Random(1) = 0) then
                 for i:= Random(2) downto 0 do
@@ -2050,7 +2057,7 @@
         end;
 
     HHGear^.dY := HHGear^.dY + cGravity;
-    if not (HHGear^.dY.isNegative) then
+    if (not HHGear^.dY.isNegative) then
         begin
         HHGear^.State := HHGear^.State or gstMoving;
         DeleteGear(Gear);
@@ -2159,7 +2166,7 @@
     AllInactive := false;
     Gear^.X := Gear^.X + cAirPlaneSpeed * Gear^.Tag;
 
-    if (Gear^.Health > 0)and(not (Gear^.X < Gear^.dX))and(Gear^.X < Gear^.dX + cAirPlaneSpeed) then
+    if (Gear^.Health > 0) and (not (Gear^.X < Gear^.dX)) and (Gear^.X < Gear^.dX + cAirPlaneSpeed) then
         begin
         dec(Gear^.Health);
             case Gear^.State of
@@ -2227,9 +2234,11 @@
         begin
         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound);
         DeleteGear(Gear);
+        {$IFNDEF PAS2C}
         with mobileRecord do
             if (performRumble <> nil) and (not fastUntilLag) then
                 performRumble(kSystemSoundID_Vibrate);
+        {$ENDIF}
         exit
         end;
     if (GameTicks and $3F) = 0 then
@@ -2252,7 +2261,7 @@
     y := HHGear^.Y;
 
     if (Distance(tx - x, ty - y) > _256)
-    or (not TryPlaceOnLand(Gear^.Target.X - SpritesData[sprAmGirder].Width div 2, Gear^.Target.Y - SpritesData[sprAmGirder].Height div 2, sprAmGirder, Gear^.State, true, false)) then
+    or (not (TryPlaceOnLand(Gear^.Target.X - SpritesData[sprAmGirder].Width div 2, Gear^.Target.Y - SpritesData[sprAmGirder].Height div 2, sprAmGirder, Gear^.State, true, false))) then
         begin
         PlaySound(sndDenied);
         HHGear^.Message := HHGear^.Message and (not gmAttack);
@@ -2314,9 +2323,9 @@
     AllInactive := false;
 
     HHGear := Gear^.Hedgehog^.Gear;
-    if not TryPlaceOnLand(Gear^.Target.X - SpritesData[sprHHTelepMask].Width div 2,
+    if (not (TryPlaceOnLand(Gear^.Target.X - SpritesData[sprHHTelepMask].Width div 2,
         Gear^.Target.Y - SpritesData[sprHHTelepMask].Height div 2,
-        sprHHTelepMask, 0, false, false) then
+        sprHHTelepMask, 0, false, false))) then
         begin
         HHGear^.Message := HHGear^.Message and (not gmAttack);
         HHGear^.State := HHGear^.State and (not gstAttacking);
@@ -2328,7 +2337,7 @@
     else
         begin
         DeleteCI(HHGear);
-        SetAllHHToActive;
+        SetAllHHToActive(true);
         Gear^.doStep := @doStepTeleportAnim;
 
   // copy old HH position and direction to Gear (because we need them for drawing the vanishing hog)
@@ -2913,7 +2922,7 @@
     if (Gear^.Timer = 0) or ((t <> nil) and (t^.Count <> 0))
     or ( ((Gear^.State and gsttmpFlag) = 0) and (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))))
 // CheckLandValue returns true if the type isn't matched
-    or (not CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y), lfIndestructible)) then
+    or (not (CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y), lfIndestructible))) then
         begin
         //out of time or exited ground
         StopSoundChan(Gear^.SoundChannel);
@@ -2925,7 +2934,7 @@
         exit
         end
 
-    else if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))) then
+    else if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not (TestCollisionXWithGear(Gear, hwSign(Gear^.dX)))) then
         begin
         StopSoundChan(Gear^.SoundChannel);
         Gear^.Tag := 1;
@@ -3288,7 +3297,7 @@
     Gear^.X := HHGear^.X;
     Gear^.Y := HHGear^.Y;
 
-    if not isUnderWater and hasBorder and ((HHGear^.X < _0)
+    if (not isUnderWater) and hasBorder and ((HHGear^.X < _0)
     or (hwRound(HHGear^.X) > LAND_WIDTH)) then
         HHGear^.dY.isNegative:= false;
 
@@ -3541,7 +3550,9 @@
     i: LongInt;
 begin
     AllInactive := false;
+    {$IFNDEF PAS2C}
     Gear^.dX := Gear^.dX;
+    {$ENDIF}
     doStepFallingGear(Gear);
     //    CheckGearDrowning(Gear); // already checked for in doStepFallingGear
     CalcRotationDirAngle(Gear);
@@ -3682,18 +3693,18 @@
         // won't port stuff that does not move towards the front/portal entrance
         if iscake then
             begin
-            if not (((iterator^.X - Gear^.X)*ox + (iterator^.Y - Gear^.Y)*oy).isNegative) then
+            if (not (((iterator^.X - Gear^.X)*ox + (iterator^.Y - Gear^.Y)*oy).isNegative)) then
                 continue;
             end
         else
-            if not ((Gear^.dX*ox + Gear^.dY*oy).isNegative) then
+            if (not ((Gear^.dX*ox + Gear^.dY*oy).isNegative)) then
                 continue;
 
         isbullet:= (iterator^.Kind in [gtShotgunShot, gtDEagleShot, gtSniperRifleShot, gtSineGunShot]);
 
         r:= int2hwFloat(iterator^.Radius);
 
-        if not (isbullet or iscake) then
+        if (not (isbullet or iscake)) then
             begin
             // wow! good candidate there, let's see if the distance and direction is okay!
             if hasdxy then
@@ -3725,7 +3736,7 @@
         oy := (iterator^.Y - Gear^.Y);
         poffs:= (Gear^.dX * ox + Gear^.dY * oy);
 
-        if not isBullet and poffs.isNegative then
+        if (not isBullet) and poffs.isNegative then
             continue;
 
         // only port bullets close to the portal
@@ -3752,7 +3763,7 @@
         if Gear^.Elasticity.isNegative then
             nx.isNegative := (not nx.isNegative)
         else
-            ny.isNegative := not ny.isNegative;
+            ny.isNegative := (not ny.isNegative);
 
         // calc gear offset in portal normal vector direction
         noffs:= (nx * ox + ny * oy);
@@ -3761,7 +3772,7 @@
             continue;
 
         // avoid gravity related loops of not really moving gear
-        if not (iscake or isbullet)
+        if (not (iscake or isbullet))
         and (Gear^.dY.isNegative)
         and (conPortal^.dY.isNegative)
         and ((iterator^.dX.QWordValue + iterator^.dY.QWordValue) < _0_08.QWordValue)
@@ -3786,7 +3797,7 @@
         if conPortal^.Elasticity.isNegative then
             nx.isNegative := (not nx.isNegative)
         else
-            ny.isNegative := not ny.isNegative;
+            ny.isNegative := (not ny.isNegative);
 
         // inverse cake's normal movement direction,
         // as if it just walked through a hole
@@ -3822,14 +3833,14 @@
         iterator^.X := conPortal^.X + poffs * conPortal^.dX + noffs * nx;
         iterator^.Y := conPortal^.Y + poffs * conPortal^.dY + noffs * ny;
 
-        if not hasdxy and (not (conPortal^.dY.isNegative)) then
+        if (not hasdxy) and (not (conPortal^.dY.isNegative)) then
             begin
             iterator^.dY:= iterator^.dY + hwAbs(cGravity * (iterator^.Y - conPortal^.Y))
             end;
 
         // see if the space on the exit side actually is enough
 
-        if not (isBullet or isCake) then
+        if (not (isBullet or isCake)) then
             begin
             // TestCollisionXwithXYShift requires a hwFloat for xShift
             ox.QWordValue := _1.QWordValue;
@@ -3845,7 +3856,7 @@
             isCollision := TestCollisionY(iterator, sy)
                         or TestCollisionX(iterator, sx);
 
-            if not isCollision then
+            if (not isCollision) then
                 begin
                 // check center area (with half the radius so that the
                 // the square check won't check more pixels than we want to)
@@ -3897,7 +3908,7 @@
             resetdy:=hwAbs(iterator^.dX*4);
             resetdy:= resetdy + hwPow(resetdy,3)/_6 + _3 * hwPow(resetdy,5) / _40 + _5 * hwPow(resetdy,7) / resety + resetx * hwPow(resetdy,9) / resetdx;
             iterator^.Angle:= hwRound(resetdy*_2048 / _PI);
-            if not iterator^.dY.isNegative then iterator^.Angle:= 2048-iterator^.Angle;
+            if (not iterator^.dY.isNegative) then iterator^.Angle:= 2048-iterator^.Angle;
             if iterator^.dX.isNegative then iterator^.Angle:= 4096-iterator^.Angle;
             end
         // VISUAL USE OF ANGLE ONLY
@@ -3914,7 +3925,7 @@
         and (CurAmmoGear^.Kind =gtRope) then
                CurAmmoGear^.PortalCounter:= 1;
 
-        if not isbullet and (iterator^.State and gstInvisible = 0)
+        if (not isbullet) and (iterator^.State and gstInvisible = 0)
         and (iterator^.Kind <> gtFlake) then
             FollowGear := iterator;
 
@@ -3976,7 +3987,7 @@
         Gear^.State := Gear^.State and (not gstMoving);
 
         if (Land[y, x] and lfBouncy <> 0)
-        or (not CalcSlopeTangent(Gear, x, y, tx, ty, 255))
+        or (not (CalcSlopeTangent(Gear, x, y, tx, ty, 255)))
         or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain
             begin
             loadNewPortalBall(Gear, true);
@@ -3989,7 +4000,7 @@
         Gear^.dY := -s * tx;
 
         Gear^.DirAngle := DxDy2Angle(-Gear^.dY,Gear^.dX);
-        if not Gear^.dX.isNegative then
+        if (not Gear^.dX.isNegative) then
             Gear^.DirAngle := 180-Gear^.DirAngle;
 
         if ((Gear^.LinkedGear = nil)
@@ -4079,7 +4090,7 @@
                 iterator:= GearsList;
                 while iterator <> nil do
                     begin
-                    if not (iterator^.Kind in [gtPortal, gtAirAttack, gtKnife]) and ((iterator^.Hedgehog <> CurrentHedgehog)
+                    if (not (iterator^.Kind in [gtPortal, gtAirAttack, gtKnife])) and ((iterator^.Hedgehog <> CurrentHedgehog)
                     or ((iterator^.Message and gmAllStoppable) = 0)) then
                             begin
                             iterator^.Active:= true;
@@ -4334,9 +4345,11 @@
     Gear^.dY.isNegative := not Gear^.dY.isNegative;
 
     Gear^.doStep := @doStepSineGunShotWork;
+    {$IFNDEF PAS2C}
     with mobileRecord do
         if (performRumble <> nil) and (not fastUntilLag) then
             performRumble(kSystemSoundID_Vibrate);
+    {$ENDIF}
 end;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -5248,7 +5261,7 @@
                         end;
 
                     // FillRoundInLandWithIce(Target.X, Target.Y, iceRadius);
-                    SetAllHHToActive;
+                    SetAllHHToActive(true);
                     Timer := iceWaitCollision;
                     end;
 
@@ -5256,7 +5269,7 @@
                     begin
                     PlaySound(sndHogFreeze);
                     DrawIceBreak(Target.X, cWaterLine - iceHeight, iceRadius, iceHeight);
-                    SetAllHHToActive;
+                    SetAllHHToActive(true);
                     Timer := iceWaitCollision;
                     end;
 (*
@@ -5333,7 +5346,7 @@
         begin
         with gi^ do CheckSum:= CheckSum xor X.round xor X.frac xor dX.round xor dX.frac xor Y.round xor Y.frac xor dY.round xor dY.frac;
         AddRandomness(CheckSum);
-        if gi^.Kind = gtGenericFaller then gi^.State:= gi^.State and not gstTmpFlag;
+        if gi^.Kind = gtGenericFaller then gi^.State:= gi^.State and (not gstTmpFlag);
         gi := gi^.NextGear
         end;
     AddPickup(Gear^.Hedgehog^, a, Gear^.Power, hwRound(Gear^.X), hwRound(Gear^.Y));
@@ -5433,7 +5446,7 @@
         begin
         tdX:= HHGear^.X-Gear^.X;
         dir:= hwSign(tdX);
-        if not TestCollisionX(Gear, dir) then
+        if (not TestCollisionX(Gear, dir)) then
             Gear^.X:= Gear^.X + signAs(_1,tdX);
         if TestCollisionXwithXYShift(Gear, signAs(_10,tdX), 0, dir) then
             begin
@@ -5506,8 +5519,8 @@
     else if GameTicks and $3F = 0 then
         begin
         if  (TestCollisionYwithGear(Gear, -1) = 0)
-        and (not TestCollisionXwithGear(Gear, 1))
-        and (not TestCollisionXwithGear(Gear, -1))
+        and (not (TestCollisionXwithGear(Gear, 1)))
+        and (not (TestCollisionXwithGear(Gear, -1)))
         and (TestCollisionYwithGear(Gear, 1) = 0) then Gear^.State:= Gear^.State and (not gstCollision) or gstMoving;
         end
 end;
--- a/hedgewars/LuaPas.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/LuaPas.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -15,7 +15,9 @@
 {.$DEFINE LUA_GETHOOK}
 
 type
+{$IFNDEF PAS2C}
     size_t   = Cardinal;
+{$ENDIF}
     Psize_t  = ^size_t;
     PPointer = ^Pointer;
 
@@ -52,12 +54,14 @@
 @* of a function in debug information.
 ** CHANGE it if you want a different size.
 *)
+
 const
     LUA_IDSIZE = 60;
 
 (*
 @@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
 *)
+
 const
     LUAL_BUFFERSIZE = 1024;
 
@@ -67,6 +71,7 @@
 ** CHANGE them if you want different prompts. (You can also change the
 ** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.)
 *)
+
 const
     LUA_PROMPT  = '> ';
     LUA_PROMPT2 = '>> ';
@@ -110,6 +115,7 @@
 ** See Copyright Notice at the end of this file
 *)
 
+
 const
     LUA_VERSION     = 'Lua 5.1';
     LUA_VERSION_NUM = 501;
@@ -129,8 +135,10 @@
     LUA_ENVIRONINDEX  = -10001;
     LUA_GLOBALSINDEX  = -10002;
 
+   
 function lua_upvalueindex(idx : LongInt) : LongInt;   // a marco
 
+
 const
    (* thread status; 0 is OK *)
     LUA_YIELD_    = 1;     // Note: the ending underscore is needed in Pascal
@@ -139,6 +147,7 @@
     LUA_ERRMEM    = 4;
     LUA_ERRERR    = 5;
 
+   
 type
    lua_CFunction = function(L : Plua_State) : LongInt; cdecl;
 
@@ -153,6 +162,7 @@
   *)
   lua_Alloc = function (ud, ptr : Pointer; osize, nsize : size_t) : Pointer; cdecl;
 
+
 const
     (*
     ** basic types
@@ -178,6 +188,7 @@
     (* type for integer functions *)
     lua_Integer = LUA_INTEGER_;
 
+   
 (*
 ** state manipulation
 *)
@@ -238,10 +249,9 @@
     
 function lua_type(L : Plua_State; idx : LongInt) : LongInt;
     cdecl; external LuaLibName;
-    
+
 function lua_typename(L : Plua_State; tp : LongInt) : PChar;
     cdecl; external LuaLibName;
-
     
 function lua_equal(L : Plua_State; idx1, idx2 : LongInt) : LongBool;
     cdecl; external LuaLibName;
@@ -261,10 +271,9 @@
 function lua_toboolean(L : Plua_State; idx : LongInt) : LongBool;
     cdecl; external LuaLibName;
     
-    
 function lua_tolstring(L : Plua_State; idx : LongInt; len : Psize_t) : PChar;
     cdecl; external LuaLibName;
-    
+
 function lua_objlen(L : Plua_State; idx : LongInt) : size_t;
     cdecl; external LuaLibName;
     
@@ -292,14 +301,13 @@
     
 procedure lua_pushinteger(L : Plua_State; n : lua_Integer);
     cdecl; external LuaLibName;
-    
+
 procedure lua_pushlstring(L : Plua_State; const s : PChar; ls : size_t);
     cdecl; external LuaLibName;
     
 procedure lua_pushstring(L : Plua_State; const s : PChar);
     cdecl; external LuaLibName;
     
-    
 function  lua_pushvfstring(L : Plua_State;
     const fmt : PChar; argp : Pointer) : PChar;
     cdecl; external LuaLibName;
@@ -325,10 +333,10 @@
 *)
 procedure lua_gettable(L : Plua_State ; idx : LongInt);
     cdecl; external LuaLibName;
-    
+
 procedure lua_getfield(L : Plua_State; idx : LongInt; k : PChar);
     cdecl; external LuaLibName;
-    
+
 procedure lua_rawget(L : Plua_State; idx : LongInt);
     cdecl; external LuaLibName;
     
@@ -353,10 +361,10 @@
 *)
 procedure lua_settable(L : Plua_State; idx : LongInt);
     cdecl; external LuaLibName;
-    
+
 procedure lua_setfield(L : Plua_State; idx : LongInt; const k : PChar);
     cdecl; external LuaLibName;
-    
+
 procedure lua_rawset(L : Plua_State; idx : LongInt);
     cdecl; external LuaLibName;
     
@@ -404,6 +412,7 @@
 (*
 ** garbage-collection functions and options
 *)
+
 const
     LUA_GCSTOP       = 0;
     LUA_GCRESTART    = 1;
@@ -413,7 +422,7 @@
     LUA_GCSTEP       = 5;
     LUA_GCSETPAUSE   = 6;
     LUA_GCSETSTEPMUL = 7;
-
+   
 function lua_gc(L : Plua_State; what, data : LongInt) : LongInt;
     cdecl; external LuaLibName;
 
--- a/hedgewars/SDLMain.h	Sun Jun 09 12:20:19 2013 +0200
+++ /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.m	Sun Jun 09 12:20:19 2013 +0200
+++ /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/SDLh.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/SDLh.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -241,7 +241,11 @@
     SDL_SRCCOLORKEY = $00001000;
     SDL_RLEACCEL    = $00004000;
     SDL_SRCALPHA    = $00010000;
+ {$IFDEF PAS2C}
+    SDL_ANYFORMAT   = $10000000;
+ {$ELSE}
     SDL_ANYFORMAT   = $00100000;
+ {$ENDIF}
     SDL_HWPALETTE   = $20000000;
     SDL_DOUBLEBUF   = $40000000;
     SDL_FULLSCREEN  = $80000000;
@@ -400,7 +404,7 @@
 {$ENDIF}
         end;
 
-    TSDL_eventaction = (SDL_ADDEVENT, SDL_PEEPEVENT, SDL_GETEVENT);
+    TSDL_eventaction = (SDL_ADDEVENT, SDL_PEEKEVENT, SDL_GETEVENT);
 
     PSDL_Surface = ^TSDL_Surface;
     TSDL_Surface = record
@@ -410,6 +414,16 @@
         pitch : {$IFDEF SDL13}LongInt{$ELSE}Word{$ENDIF};
         pixels: Pointer;
         offset: LongInt;
+{$IFDEF PAS2C}
+	hwdata:Pointer;
+	clip_rect:TSDL_Rect;
+        unsed1:LongWord;
+        locked:LongWord;
+        map:Pointer;
+        format_version:Longword;
+        refcount:LongInt;
+{$ELSE}
+		      
 {$IFDEF SDL13}
         userdata: Pointer;
         locked: LongInt;
@@ -418,6 +432,7 @@
         map: Pointer;
         refcount: LongInt;
 {$ENDIF}
+{$ENDIF}
         end;
 
 
@@ -760,6 +775,7 @@
 
     TByteArray = array[0..65535] of Byte;
     PByteArray = ^TByteArray;
+
     TLongWordArray = array[0..16383] of LongWord;
     PLongWordArray = ^TLongWordArray;
 
@@ -1127,22 +1143,31 @@
     SDL_EnableKeyRepeat:= 0;
 end;
 {$ELSE}
-const conversionFormat: TSDL_PixelFormat = (
+const convFormat:TSDL_PixelFormat = (
         palette: nil; BitsPerPixel: 32; BytesPerPixel: 4;
         Rloss: 0; Gloss: 0; Bloss: 0; Aloss: 0;
         Rshift: RShift; Gshift: GShift; Bshift: BShift; Ashift: AShift;
+
+        //TODO: FIXME in pas2c
+        {$IFDEF WEBGL}
+        Rmask: RMask; Gmask: GMask; Bmask: BMask; Amask: AMask;
+        {$ELSE}
         RMask: RMask; GMask: GMask; BMask: BMask; AMask: AMask;
-        colorkey: 0; alpha: 255);
+        colorkey: 0; alpha: 255
+        {$ENDIF}
+        );
 
 function SDL_AllocFormat(format: LongWord): PSDL_PixelFormat;
 begin
     format:= format;
-    SDL_AllocFormat:= @conversionFormat;
+    SDL_AllocFormat:= @convFormat;
 end;
 
 procedure SDL_FreeFormat(pixelformat: PSDL_PixelFormat);
 begin
+   {$IFNDEF PAS2C}
     pixelformat:= pixelformat;  // avoid hint
+   {$ENDIF}
 end;
 {$ENDIF}
 
@@ -1152,7 +1177,7 @@
 {$IFDEF SDL13}
         ((surface^.flags and SDL_RLEACCEL) <> 0)
 {$ELSE}
-        ( surface^.offset <> 0 ) or (( surface^.flags and (SDL_HWSURFACE or SDL_ASYNCBLIT or SDL_RLEACCEL)) <> 0)
+        {$IFNDEF WEBGL}( surface^.offset <> 0 ) or {$ENDIF}(( surface^.flags and (SDL_HWSURFACE or SDL_ASYNCBLIT or SDL_RLEACCEL)) <> 0)
 {$ENDIF}
 end;
 
--- a/hedgewars/VGSHandlers.inc	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/VGSHandlers.inc	Sun Jun 09 12:22:53 2013 +0200
@@ -60,8 +60,8 @@
     else
         if Angle < - 360 then
             Angle:= Angle + 360;
-    
-  
+
+
     if (round(X) >= cLeftScreenBorder)
     and (round(X) <= cRightScreenBorder)
     and (round(Y) - 75 <= LAND_HEIGHT)
@@ -197,7 +197,9 @@
 ////////////////////////////////////////////////////////////////////////////////
 procedure doStepLineTrail(Gear: PVisualGear; Steps: Longword);
 begin
+{$IFNDEF PAS2C}
 Steps := Steps;
+{$ENDIF}
 if Gear^.Timer <= Steps then
     DeleteVisualGear(Gear)
 else
@@ -464,7 +466,9 @@
     b: boolean;
     t: LongInt;
 begin
+{$IFNDEF PAS2C}
 Steps:= Steps; // avoid compiler hint
+{$ENDIF}
 
 for t:= 0 to Pred(TeamsCount) do
     with thexchar[t] do
@@ -532,7 +536,10 @@
 
 procedure doStepSpeechBubble(Gear: PVisualGear; Steps: Longword);
 begin
+
+{$IFNDEF PAS2C}
 Steps:= Steps; // avoid compiler hint
+{$ENDIF}
 
 with Gear^.Hedgehog^ do
     if SpeechGear <> nil then
@@ -637,10 +644,10 @@
 begin
 gX:= round(Gear^.X);
 gY:= round(Gear^.Y);
-for i:= 0 to 31 do 
+for i:= 0 to 31 do
     begin
     vg:= AddVisualGear(gX, gY, vgtFire);
-    if vg <> nil then 
+    if vg <> nil then
         begin
         vg^.State:= gstTmpFlag;
         inc(vg^.FrameTicks, vg^.FrameTicks)
@@ -681,10 +688,10 @@
 gX:= round(Gear^.X);
 gY:= round(Gear^.Y);
 AddVisualGear(gX, gY, vgtSmokeRing);
-for i:= 0 to 46 do 
+for i:= 0 to 46 do
     begin
     vg:= AddVisualGear(gX, gY, vgtFire);
-    if vg <> nil then 
+    if vg <> nil then
         begin
         vg^.State:= gstTmpFlag;
         inc(vg^.FrameTicks, vg^.FrameTicks)
@@ -697,9 +704,12 @@
 Gear^.doStep:= @doStepBigExplosionWork;
 if Steps > 1 then
     Gear^.doStep(Gear, Steps-1);
+
+{$IFNDEF PAS2C}
 with mobileRecord do
     if (performRumble <> nil) and (not fastUntilLag) then
         performRumble(kSystemSoundID_Vibrate);
+{$ENDIF}
 end;
 
 procedure doStepChunk(Gear: PVisualGear; Steps: Longword);
@@ -761,7 +771,7 @@
 procedure doStepSmoothWindBar(Gear: PVisualGear; Steps: Longword);
 begin
 inc(Gear^.Timer, Steps);
-    
+
 while Gear^.Timer >= 10 do
     begin
     dec(Gear^.Timer, 10);
@@ -780,8 +790,8 @@
     cWindspeedf := cWindspeedf + Gear^.Angle*Steps;
     if cWindspeedf > Gear^.dAngle then cWindspeedf:= Gear^.dAngle;
     end;
-        
-if (WindBarWidth = Gear^.Tag) and (cWindspeedf = Gear^.dAngle)  then 
+
+if (WindBarWidth = Gear^.Tag) and (cWindspeedf = Gear^.dAngle)  then
     DeleteVisualGear(Gear)
 end;
 ////////////////////////////////////////////////////////////////////////////////
@@ -795,7 +805,7 @@
 else
     begin
     dec(Gear^.FrameTicks, Steps);
-    if (Gear^.FrameTicks < 501) and (Gear^.FrameTicks mod 5 = 0) then 
+    if (Gear^.FrameTicks < 501) and (Gear^.FrameTicks mod 5 = 0) then
         Gear^.Tint:= (Gear^.Tint and $FFFFFF00) or (((Gear^.Tint and $000000FF) * Gear^.FrameTicks) div 500)
     end
 end;
--- a/hedgewars/adler32.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/adler32.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -2,8 +2,8 @@
 
 {ZLib - Adler32 checksum function}
 
-
 interface
+uses uTypes;
 
 (*************************************************************************
 
@@ -66,7 +66,7 @@
 Also, the structure was removed to simplify C conversion
 *)
 
-function Adler32Update ( var adler     :longint; Msg     :pointer; Len     :longint ) : longint;
+function Adler32Update (var adler : longint; Msg     :Pointer; Len     :longint ) : longint;
 
 implementation
 
@@ -124,17 +124,19 @@
 end;
 *)
 
-function Adler32Update(var adler: longint; Msg: pointer; Len :longint) : longint;
+function Adler32Update(var adler:longint; Msg: Pointer; Len :longint) : longint;
     {-update Adler32 with Msg data}
     const
         BASE = 65521; {max. prime < 65536 }
         NMAX = 3854; {max. n with 255n(n+1)/2 + (n+1)(BASE-1) < 2^31}
     var
-        s1, s2: longint;
-        i, n: integer;
+        s1, s2 : longint;
+        i, n   : integer;
+       m       : PByte;
     begin
-        s1 := adler and $FFFF;
-        s2 := adler shr 16;
+        m  := PByte(Msg);
+        s1 := Longword(adler) and $FFFF;
+        s2 := Longword(adler) shr 16;
         while Len>0 do
             begin
             if Len<NMAX then
@@ -144,8 +146,8 @@
 
             for i := 1 to n do
                 begin
-                inc(s1, pByte(Msg)^);
-                inc(Msg);
+                inc(s1, m^);
+                inc(m);
                 inc(s2, s1);
                 end;
             s1 := s1 mod BASE;
--- a/hedgewars/avwrapper.c	Sun Jun 09 12:20:19 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,509 +0,0 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdarg.h>
-#include "libavformat/avformat.h"
-#include "libavutil/mathematics.h"
-
-#ifndef AVIO_FLAG_WRITE
-#define AVIO_FLAG_WRITE AVIO_WRONLY
-#endif
-
-static AVFormatContext* g_pContainer;
-static AVOutputFormat* g_pFormat;
-static AVStream* g_pAStream;
-static AVStream* g_pVStream;
-static AVFrame* g_pAFrame;
-static AVFrame* g_pVFrame;
-static AVCodec* g_pACodec;
-static AVCodec* g_pVCodec;
-static AVCodecContext* g_pAudio;
-static AVCodecContext* g_pVideo;
-
-static int g_Width, g_Height;
-static uint32_t g_Frequency, g_Channels;
-static int g_VQuality;
-static AVRational g_Framerate;
-
-static FILE* g_pSoundFile;
-static int16_t* g_pSamples;
-static int g_NumSamples;
-
-
-#if LIBAVCODEC_VERSION_MAJOR < 54
-#define OUTBUFFER_SIZE 200000
-static uint8_t g_OutBuffer[OUTBUFFER_SIZE];
-#endif
-
-// pointer to function from hwengine (uUtils.pas)
-static void (*AddFileLogRaw)(const char* pString);
-
-static void FatalError(const char* pFmt, ...)
-{
-    char Buffer[1024];
-    va_list VaArgs;
-
-    va_start(VaArgs, pFmt);
-    vsnprintf(Buffer, 1024, pFmt, VaArgs);
-    va_end(VaArgs);
-
-    AddFileLogRaw("Error in av-wrapper: ");
-    AddFileLogRaw(Buffer);
-    AddFileLogRaw("\n");
-    exit(1);
-}
-
-// Function to be called from libav for logging.
-// Note: libav can call LogCallback from different threads
-// (there is mutex in AddFileLogRaw).
-static void LogCallback(void* p, int Level, const char* pFmt, va_list VaArgs)
-{
-    char Buffer[1024];
-
-    vsnprintf(Buffer, 1024, pFmt, VaArgs);
-    AddFileLogRaw(Buffer);
-}
-
-static void Log(const char* pFmt, ...)
-{
-    char Buffer[1024];
-    va_list VaArgs;
-
-    va_start(VaArgs, pFmt);
-    vsnprintf(Buffer, 1024, pFmt, VaArgs);
-    va_end(VaArgs);
-
-    AddFileLogRaw(Buffer);
-}
-
-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");
-        return;
-    }
-    g_pAStream->id = 1;
-
-    g_pAudio = g_pAStream->codec;
-
-    avcodec_get_context_defaults3(g_pAudio, g_pACodec);
-    g_pAudio->codec_id = g_pACodec->id;
-
-    // put parameters
-    g_pAudio->sample_fmt = AV_SAMPLE_FMT_S16;
-    g_pAudio->sample_rate = g_Frequency;
-    g_pAudio->channels = g_Channels;
-
-    // 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->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;
-
-    // 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)
-#else
-    if (g_pAudio->frame_size == 0)
-#endif
-        g_NumSamples = 4096;
-    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();
-    if (!g_pAFrame)
-    {
-        Log("Could not allocate frame\n");
-        return;
-    }
-}
-
-// returns non-zero if there is more sound
-static int WriteAudioFrame()
-{
-    if (!g_pAStream)
-        return 0;
-
-    AVPacket Packet = { 0 };
-    av_init_packet(&Packet);
-
-    int NumSamples = fread(g_pSamples, 2*g_Channels, g_NumSamples, g_pSoundFile);
-
-#if LIBAVCODEC_VERSION_MAJOR >= 53
-    AVFrame* pFrame = NULL;
-    if (NumSamples > 0)
-    {
-        g_pAFrame->nb_samples = NumSamples;
-        avcodec_fill_audio_frame(g_pAFrame, g_Channels, AV_SAMPLE_FMT_S16,
-                                 (uint8_t*)g_pSamples, NumSamples*2*g_Channels, 1);
-        pFrame = g_pAFrame;
-    }
-    // when NumSamples == 0 we still need to call encode_audio2 to flush
-    int got_packet;
-    if (avcodec_encode_audio2(g_pAudio, &Packet, pFrame, &got_packet) != 0)
-        FatalError("avcodec_encode_audio2 failed");
-    if (!got_packet)
-        return 0;
-#else
-    if (NumSamples == 0)
-        return 0;
-    int BufferSize = OUTBUFFER_SIZE;
-    if (g_pAudio->frame_size == 0)
-        BufferSize = NumSamples*g_Channels*2;
-    Packet.size = avcodec_encode_audio(g_pAudio, g_OutBuffer, BufferSize, g_pSamples);
-    if (Packet.size == 0)
-        return 1;
-    if (g_pAudio->coded_frame && g_pAudio->coded_frame->pts != AV_NOPTS_VALUE)
-        Packet.pts = av_rescale_q(g_pAudio->coded_frame->pts, g_pAudio->time_base, g_pAStream->time_base);
-    Packet.flags |= AV_PKT_FLAG_KEY;
-    Packet.data = g_OutBuffer;
-#endif
-
-    // Write the compressed frame to the media file.
-    Packet.stream_index = g_pAStream->index;
-    if (av_interleaved_write_frame(g_pContainer, &Packet) != 0) 
-        FatalError("Error while writing audio frame");
-    return 1;
-}
-
-// add a video output stream
-static void 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)
-        FatalError("Could not allocate video stream");
-
-    g_pVideo = g_pVStream->codec;
-
-    avcodec_get_context_defaults3(g_pVideo, g_pVCodec);
-    g_pVideo->codec_id = g_pVCodec->id;
-
-    // put parameters
-    // resolution must be a multiple of two
-    g_pVideo->width  = g_Width  & ~1; // make even (dimensions should be even)
-    g_pVideo->height = g_Height & ~1; // make even
-    /* time base: this is the fundamental unit of time (in seconds) in terms
-       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;
-
-    // set quality
-    if (g_VQuality > 100)
-        g_pVideo->bit_rate = g_VQuality;
-    else
-    {
-        g_pVideo->flags |= 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;
-
-#if LIBAVCODEC_VERSION_MAJOR < 53
-    // for some versions of ffmpeg x264 options must be set explicitly
-    if (strcmp(g_pVCodec->name, "libx264") == 0)
-    {
-        g_pVideo->coder_type = FF_CODER_TYPE_AC;
-        g_pVideo->flags |= CODEC_FLAG_LOOP_FILTER;
-        g_pVideo->crf = 23;
-        g_pVideo->thread_count = 3;
-        g_pVideo->me_cmp = FF_CMP_CHROMA;
-        g_pVideo->partitions = X264_PART_I8X8 | X264_PART_I4X4 | X264_PART_P8X8 | X264_PART_B8X8;
-        g_pVideo->me_method = ME_HEX;
-        g_pVideo->me_subpel_quality = 7;
-        g_pVideo->me_range = 16;
-        g_pVideo->gop_size = 250;
-        g_pVideo->keyint_min = 25;
-        g_pVideo->scenechange_threshold = 40;
-        g_pVideo->i_quant_factor = 0.71;
-        g_pVideo->b_frame_strategy = 1;
-        g_pVideo->qcompress = 0.6;
-        g_pVideo->qmin = 10;
-        g_pVideo->qmax = 51;
-        g_pVideo->max_qdiff = 4;
-        g_pVideo->max_b_frames = 3;
-        g_pVideo->refs = 3;
-        g_pVideo->directpred = 1;
-        g_pVideo->trellis = 1;
-        g_pVideo->flags2 = CODEC_FLAG2_BPYRAMID | CODEC_FLAG2_MIXED_REFS | CODEC_FLAG2_WPRED | CODEC_FLAG2_8X8DCT | CODEC_FLAG2_FASTPSKIP;
-        g_pVideo->weighted_p_pred = 2;
-    }
-#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
-        FatalError("Could not open video codec %s", g_pVCodec->long_name);
-
-    g_pVFrame = avcodec_alloc_frame();
-    if (!g_pVFrame)
-        FatalError("Could not allocate frame");
-
-    g_pVFrame->linesize[0] = g_Width;
-    g_pVFrame->linesize[1] = g_Width/2;
-    g_pVFrame->linesize[2] = g_Width/2;
-    g_pVFrame->linesize[3] = 0;
-}
-
-static int WriteFrame(AVFrame* pFrame)
-{
-    double AudioTime, VideoTime;
-
-    // write interleaved audio frame
-    if (g_pAStream)
-    {
-        VideoTime = (double)g_pVStream->pts.val*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;
-        while (AudioTime < VideoTime && WriteAudioFrame());
-    }
-    
-    if (!g_pVStream)
-        return 0;
-
-    AVPacket Packet;
-    av_init_packet(&Packet);
-    Packet.data = NULL;
-    Packet.size = 0;
-
-    g_pVFrame->pts++;
-    if (g_pFormat->flags & AVFMT_RAWPICTURE)
-    {
-        /* raw video case. The API will change slightly in the near
-           future for that. */
-        Packet.flags |= AV_PKT_FLAG_KEY;
-        Packet.stream_index = g_pVStream->index;
-        Packet.data = (uint8_t*)pFrame;
-        Packet.size = sizeof(AVPicture);
-
-        if (av_interleaved_write_frame(g_pContainer, &Packet) != 0)
-            FatalError("Error while writing video frame");
-        return 0;
-    }
-    else
-    {
-#if LIBAVCODEC_VERSION_MAJOR >= 54
-        int got_packet;
-        if (avcodec_encode_video2(g_pVideo, &Packet, pFrame, &got_packet) < 0)
-            FatalError("avcodec_encode_video2 failed");
-        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);
-#else 
-        Packet.size = avcodec_encode_video(g_pVideo, g_OutBuffer, OUTBUFFER_SIZE, pFrame);
-        if (Packet.size < 0)
-            FatalError("avcodec_encode_video failed");
-        if (Packet.size == 0)
-            return 0;
-
-        if( g_pVideo->coded_frame->pts != AV_NOPTS_VALUE)
-            Packet.pts = av_rescale_q(g_pVideo->coded_frame->pts, g_pVideo->time_base, g_pVStream->time_base);
-        if( g_pVideo->coded_frame->key_frame )
-            Packet.flags |= AV_PKT_FLAG_KEY;
-        Packet.data = g_OutBuffer;
-#endif
-        // write the compressed frame in the media file
-        Packet.stream_index = g_pVStream->index;
-        if (av_interleaved_write_frame(g_pContainer, &Packet) != 0)
-            FatalError("Error while writing video frame");
-            
-        return 1;
-    }
-}
-
-void AVWrapper_WriteFrame(uint8_t* pY, uint8_t* pCb, uint8_t* pCr)
-{
-    g_pVFrame->data[0] = pY;
-    g_pVFrame->data[1] = pCb;
-    g_pVFrame->data[2] = pCr;
-    WriteFrame(g_pVFrame);
-}
-
-void AVWrapper_Init(
-         void (*pAddFileLogRaw)(const char*),
-         const char* pFilename,
-         const char* pDesc,
-         const char* pSoundFile,
-         const char* pFormatName,
-         const char* pVCodecName,
-         const char* pACodecName,
-         int Width, int Height,
-         int FramerateNum, int FramerateDen,
-         int VQuality)
-{    
-    AddFileLogRaw = pAddFileLogRaw;
-    av_log_set_callback( &LogCallback );
-
-    g_Width  = Width;
-    g_Height = Height;
-    g_Framerate.num = FramerateNum;
-    g_Framerate.den = FramerateDen;
-    g_VQuality = VQuality;
-
-    // initialize libav and register all codecs and formats
-    av_register_all();
-
-    // find format
-    g_pFormat = av_guess_format(pFormatName, NULL, NULL);
-    if (!g_pFormat)
-        FatalError("Format \"%s\" was not found", pFormatName);
-
-    // allocate the output media context
-    g_pContainer = avformat_alloc_context();
-    if (!g_pContainer)
-        FatalError("Could not allocate output context");
-
-    g_pContainer->oformat = g_pFormat;
-
-    // store description of file
-    av_dict_set(&g_pContainer->metadata, "comment", pDesc, 0);
-
-    // append extesnion to filename
-    char ext[16];
-    strncpy(ext, g_pFormat->extensions, 16);
-    ext[15] = 0;
-    ext[strcspn(ext,",")] = 0;
-    snprintf(g_pContainer->filename, sizeof(g_pContainer->filename), "%s.%s", pFilename, ext);
-
-    // find codecs
-    g_pVCodec = avcodec_find_encoder_by_name(pVCodecName);
-    g_pACodec = avcodec_find_encoder_by_name(pACodecName);
-
-    // add audio and video stream to container
-    g_pVStream = NULL;
-    g_pAStream = NULL;
-
-    if (g_pVCodec)
-        AddVideoStream();
-    else
-        Log("Video codec \"%s\" was not found; video will be ignored.\n", pVCodecName);
-
-    if (g_pACodec)
-    {
-        g_pSoundFile = fopen(pSoundFile, "rb");
-        if (g_pSoundFile)
-        {
-            fread(&g_Frequency, 4, 1, g_pSoundFile);
-            fread(&g_Channels, 4, 1, g_pSoundFile);
-            AddAudioStream();
-        }
-        else
-            Log("Could not open %s\n", pSoundFile);
-    }
-    else
-        Log("Audio codec \"%s\" was not found; audio will be ignored.\n", pACodecName);
-
-    if (!g_pAStream && !g_pVStream)
-        FatalError("No video, no audio, aborting...");
-
-    // write format info to log
-    av_dump_format(g_pContainer, 0, g_pContainer->filename, 1);
-
-    // open the output file, if needed
-    if (!(g_pFormat->flags & AVFMT_NOFILE))
-    {
-        if (avio_open(&g_pContainer->pb, g_pContainer->filename, AVIO_FLAG_WRITE) < 0)
-            FatalError("Could not open output file (%s)", g_pContainer->filename);
-    }
-
-    // write the stream header, if any
-    avformat_write_header(g_pContainer, NULL);
-
-    g_pVFrame->pts = -1;
-}
-
-void AVWrapper_Close()
-{
-    // output buffered frames
-    if (g_pVCodec->capabilities & CODEC_CAP_DELAY)
-        while( WriteFrame(NULL) );
-    // output any remaining audio
-    while( WriteAudioFrame() );
-
-    // write the trailer, if any.
-    av_write_trailer(g_pContainer);
-
-    // close the output file
-    if (!(g_pFormat->flags & AVFMT_NOFILE))
-        avio_close(g_pContainer->pb);
-
-    // free everything
-    if (g_pVStream)
-    {
-        avcodec_close(g_pVideo);
-        av_free(g_pVideo);
-        av_free(g_pVStream);
-        av_free(g_pVFrame);
-    }
-    if (g_pAStream)
-    {
-        avcodec_close(g_pAudio);
-        av_free(g_pAudio);
-        av_free(g_pAStream);
-        av_free(g_pAFrame);
-        av_free(g_pSamples);
-        fclose(g_pSoundFile);
-    }
-
-    av_free(g_pContainer);
-}
Binary file hedgewars/hwengine.ico has changed
--- a/hedgewars/hwengine.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/hwengine.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -19,7 +19,7 @@
 {$INCLUDE "options.inc"}
 
 {$IFDEF WIN32}
-{$R hwengine.rc}
+{$R res/hwengine.rc}
 {$ENDIF}
 
 {$IFDEF HWLIBRARY}
@@ -36,6 +36,7 @@
      {$IFDEF USE_VIDEO_RECORDING}, uVideoRec {$ENDIF}
      {$IFDEF USE_TOUCH_INTERFACE}, uTouch {$ENDIF}
      {$IFDEF ANDROID}, GLUnit{$ENDIF}
+     {$IFDEF WEBGL}, uWeb{$ENDIF}
      ;
 
 var isInternal: Boolean;
@@ -56,6 +57,20 @@
 
 {$INCLUDE "ArgParsers.inc"}
 
+{$IFDEF WEBGL}
+procedure playFile(path: PChar); forward;
+function isEngineRunning():Integer; forward;
+procedure shutdown();forward;
+function getRealTicks():Integer; forward;
+procedure mainhook(); forward;
+var
+    args: array[0..3] of PChar;
+    PrevTime, CurrTime: LongInt;
+    isTerminated: boolean;
+    prevFocusState: boolean;
+    isRunning : boolean;
+{$ENDIF}
+
 ///////////////////////////////////////////////////////////////////////////////
 function DoTimer(Lag: LongInt): boolean;
 var s: shortstring;
@@ -95,7 +110,13 @@
             end;
         gsConfirm, gsGame, gsChat:
             begin
-            if not cOnlyStats then DrawWorld(Lag);
+            if not cOnlyStats then
+{$IFDEF WEBGL}
+                drawworld_hook();
+{$ELSE}
+                // never place between ProcessKbd and DoGameTick - bugs due to /put cmd and isCursorVisible
+                DrawWorld(Lag);
+{$ENDIF}
             DoGameTick(Lag);
             if not cOnlyStats then ProcessVisualGears(Lag);
             end;
@@ -117,7 +138,11 @@
     if flagMakeCapture then
         begin
         flagMakeCapture:= false;
+        {$IFDEF PAS2C}
+        s:= '/Screenshots/hw';
+        {$ELSE}
         s:= '/Screenshots/hw_' + FormatDateTime('YYYY-MM-DD_HH-mm-ss', Now()) + inttostr(GameTicks);
+        {$ENDIF}
 
         // flash
         playSound(sndShutter);
@@ -138,18 +163,26 @@
 ///////////////////////////////////////////////////////////////////////////////
 procedure MainLoop;
 var event: TSDL_Event;
-    PrevTime, CurrTime: Longword;
+{$IFNDEF WEBGL}
+    PrevTime, CurrTime: LongInt;
     isTerminated: boolean;
 {$IFDEF SDL13}
     previousGameState: TGameState;
 {$ELSE}
     prevFocusState: boolean;
 {$ENDIF}
+
+{$ENDIF}
+
 begin
+
+{$IFNDEF WEBGL}
     isTerminated:= false;
     PrevTime:= SDL_GetTicks;
     while isTerminated = false do
     begin
+{$ENDIF}
+
         SDL_PumpEvents();
 
         while SDL_PeepEvents(@event, 1, SDL_GETEVENT, {$IFDEF SDL13}SDL_FIRSTEVENT, SDL_LASTEVENT{$ELSE}SDL_ALLEVENTS{$ENDIF}) > 0 do
@@ -277,12 +310,24 @@
         CurrTime:= SDL_GetTicks();
         if PrevTime + longword(cTimerInterval) <= CurrTime then
         begin
-            isTerminated := isTerminated or DoTimer(CurrTime - PrevTime);
-            PrevTime:= CurrTime
+            isTerminated:= isTerminated or DoTimer(CurrTime - PrevTime);
+            PrevTime:= CurrTime;
+            {$IFDEF WEBGL}
+            if not isTerminated then
+                mainloop_hook();
+            else
+            begin
+                freeEverything(true);
+                isRunning := false;
+            end
+            {$ENDIF}
         end
-        else SDL_Delay(1);
+        else {$IFNDEF WEBGL}SDL_Delay(1){$ELSE}mainloop_hook(){$ENDIF};
         IPCCheckSock();
+
+{$IFNDEF WEBGL}
     end;
+{$ENDIF}
 end;
 
 {$IFDEF USE_VIDEO_RECORDING}
@@ -323,6 +368,10 @@
 //var p: TPathType;
 var s: shortstring;
     i: LongInt;
+{$IFDEF WEBGL}
+    l:TResourceList;
+{$ENDIF}
+
 begin
 {$IFDEF HWLIBRARY}
     preInitEverything();
@@ -405,13 +454,27 @@
 
 {$IFDEF USE_VIDEO_RECORDING}
     if GameType = gmtRecord then
-        RecorderMainLoop()
-    else
+    begin
+        RecorderMainLoop();
+        freeEverything(true);
+        exit;
+    end;
 {$ENDIF}
-        MainLoop();
 
+{$IFDEF WEBGL}
+    l := generateResourceList();
+    clear_filelist_hook();
+    for i:= 0 to l.count - 1 do
+    add_file_hook(PChar(l.files[i] + '.png'));
+    isTerminated := false;
+    isRunning := true;
+    PrevTime := SDL_GetTicks();
+    idb_loader_hook();
+{$ELSE}
+    MainLoop;
     // clean up all the memory allocated
     freeEverything(true);
+{$ENDIF}
 end;
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -531,7 +594,18 @@
 ///////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////// m a i n ///////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
+{$IFDEF WEBGL}
+procedure hwmain(argc:Integer; argv:PPChar);
+{$ENDIF}
 begin
+{$IFDEF PAS2C}
+    // workaround for pascal's ParamStr and ParamCount
+    init(argc, argv);
+{$IFDEF WEBGL}
+    // patch emscripten's SDL implementation
+    SDL_InitPatch();
+{$ENDIF}
+{$ENDIF}
     preInitEverything();
     GetParams();
 
@@ -541,6 +615,62 @@
         Game();
 
     // return 1 when engine is not called correctly
-    halt(LongInt(GameType = gmtSyntax));
+    {$IFDEF PAS2C}
+       {$IFNDEF WEBGL}
+       exit(LongInt(GameType = gmtSyntax));
+       {$ENDIF}
+    {$ELSE}
+       halt(LongInt(GameType = gmtSyntax));
+    {$ENDIF}
+
+
+{$IFDEF WEBGL}
+end;
+
+// hook
+procedure playFile(path: PChar);
+begin
+    args[0] := PChar('');
+    args[1] := PChar('');
+    args[2] := PChar('Data');
+    args[3] := path;
+    hwmain(4, args);
+end;
+
+// hook
+function isEngineRunning:Integer;
+begin
+    isEngineRunning := isRunning;
+end;
+
+// hook
+procedure shutdown;
+begin
+    GameState := gsExit;
+end;
+
+// hook
+function getRealTicks():Integer;
+begin
+    getRealTicks := RealTicks;
+end;
+
+// main
+begin
+    isRunning := false;
+
+    // avoid hooks to be eliminated by optimizer
+    if argc = 1234 then
+    begin
+        mainhook();
+        isRunning := isEngineRunning();
+        playFile(argv);
+        argc := getRealTicks();
+        DrawWorld(argc);
+        MainLoop;
+        shutdown;
+    end
+{$ENDIF}
+
 {$ENDIF}
 end.
--- a/hedgewars/hwengine.rc	Sun Jun 09 12:20:19 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-MAINICON ICON "hwengine.ico"
\ No newline at end of file
--- a/hedgewars/options.inc	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/options.inc	Sun Jun 09 12:22:53 2013 +0200
@@ -29,6 +29,14 @@
 
 {$DEFINE USE_LUA_SCRIPT}
 
+{$IF DEFINED(WEBGL) AND NOT DEFINED(PAS2C)}
+{$UNDEF WEBGL}
+{$ENDIF}
+
+{$IFDEF WEBGL}
+{$DEFINE GL2}
+{$ENDIF}
+
 {$IFDEF ANDROID}
     {$DEFINE MOBILE}
     {$DEFINE USE_CONTEXT_RESTORE}
@@ -64,12 +72,14 @@
     {$DEFINE SDL13}
 {$ENDIF}
 
+{$IFDEF PAS2C}
+    {$DEFINE NOCONSOLE}
+    {$DEFINE USE_SDLTHREADS}
+{$ENDIF}
 
-//TODO: cruft to be removed
 {$DEFINE _S:=}
 {$DEFINE _P:=}
 
-
 //{$DEFINE TRACEAIACTIONS}
 //{$DEFINE COUNTTICKS}
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/pas2cRedo.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,113 @@
+redo;
+{This file contains functions that are re-implemented}
+{pas2c will add prefix fpcrtl_ to all these functions}
+type 
+    uinteger = uinteger;
+    Integer = integer;
+    LongInt = integer;
+    LongWord = uinteger;
+    Cardinal = uinteger;
+    PtrInt = integer;
+    Word = uinteger;
+    Byte = integer;
+    SmallInt = integer;
+    ShortInt = integer;
+    Int64 = integer;
+    QWord = uinteger;
+    GLint = integer;
+    GLuint = integer;
+    int = integer;
+    size_t = integer;
+
+    pointer = pointer;
+
+    float = float;
+    single = float;
+    double = float;
+    real = float;
+    extended = float;
+    GLfloat = float;
+
+    boolean = boolean;
+    LongBool = boolean;
+
+    string = string;
+    shortstring = string;
+    ansistring = string;
+    widechar = string;
+
+    char = char;
+    PChar = ^char;
+    PPChar = ^Pchar;
+    
+    PByte = ^Byte;
+    PLongInt = ^LongInt;
+    PLongWord = ^LongWord;
+    PInteger = ^Integer;
+    
+    Handle = integer;
+
+var
+    write, writeLn, read, readLn, flush: procedure;
+
+    halt:procedure;
+
+    GetEnumName:function:shortstring;
+    TypeInfo:function:Integer;
+
+    lo:function:Integer;
+
+    init:procedure;
+
+    StrLen:function : integer;
+    odd, even : function : boolean;
+
+    Length : function : integer;
+
+    Now : function : integer;
+
+    new, dispose, FillChar, Move : procedure;
+
+    trunc, round : function : integer;
+    abs, sqr : function : integer;
+
+    StrPas, FormatDateTime, copy, delete, str, PosS, trim, LowerCase : function : shortstring;
+    pos : function : integer;
+    StrToInt : function : integer;
+    SetLength, val : procedure;
+    _pchar : function : PChar;
+    pchar2str : function : string;
+    memcpy : procedure;
+
+     min, max:function:integer;
+    assign, rewrite, rewrite_2, reset, reset_2, flush, BlockWrite, BlockRead, close : procedure;
+    FileExists, DirectoryExists, eof : function : boolean;
+    ExtractFileName : function : string;
+    
+    ParamCount : function : integer;
+    ParamStr : function : string;
+
+    arctan2, power: function : float;
+
+    //TypeInfo, GetEnumName : function : shortstring;
+
+    UTF8ToUnicode, WrapText: function : shortstring;
+
+    GetMem : function : pointer;
+    FreeMem : procedure;
+
+    BeginThread, ThreadSwitch : procedure;
+    InterlockedIncrement, InterlockedDecrement : procedure;
+
+    random : function : integer;
+    randomize : procedure;
+    
+    Assigned : function : boolean;
+
+    //EnumToStr : function : string;
+
+    initParams : procedure;
+    
+    Load_GL_VERSION_2_0 : procedure;
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/pas2cSystem.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,129 @@
+system;
+
+type 
+    uinteger = uinteger;
+    Integer = integer;
+    LongInt = integer;
+    LongWord = uinteger;
+    Cardinal = uinteger;
+    PtrInt = integer;
+    Word = uinteger;
+    Byte = integer;
+    SmallInt = integer;
+    ShortInt = integer;
+    Int64 = integer;
+    QWord = uinteger;
+    GLint = integer;
+    GLuint = integer;
+    GLenum = integer;
+
+    int = integer;
+    size_t = integer;
+
+    pointer = pointer;
+
+    float = float;
+    single = float;
+    double = float;
+    real = float;
+    extended = float;
+    GLfloat = float;
+
+    boolean = boolean;
+    LongBool = boolean;
+
+    string = string;
+    shortstring = string;
+    ansistring = string;
+    widechar = string;
+
+    char = char;
+    PChar = ^char;
+    PPChar = ^Pchar;
+    
+    PByte = ^Byte;
+    PWord = ^Word;
+    PLongInt = ^LongInt;
+    PLongWord = ^LongWord;
+    PInteger = ^Integer;
+    
+    Handle = integer;
+
+    png_structp = pointer;
+    png_size_t = integer;
+
+var 
+    false, true: boolean;
+    
+    ord, Succ, Pred : function : integer;
+    inc, dec, Low, High, Lo, Hi : function : integer;
+
+    IOResult : integer;
+    exit, break, halt, continue : procedure;
+
+    TextFile, File : Handle;
+    FileMode : integer;
+    exitcode : integer;
+    stdout, stderr : Handle;
+
+    sqrt, cos, sin: function : float;
+    pi : float;
+
+    sizeof : function : integer;
+
+    glGetString : function : pchar;
+ 
+    glBegin, glBindTexture, glBlendFunc, glClear, glClearColor,
+    glColor4ub, glColorMask, glColorPointer, glDeleteTextures,
+    glDisable, glDisableClientState, glDrawArrays, glEnable,
+    glEnableClientState, glEnd, glGenTextures, glGetIntegerv,
+    glHint, glLineWidth, glLoadIdentity, glMatrixMode, glPopMatrix,
+    glPushMatrix, glReadPixels, glRotatef, glScalef, glTexCoord2f,
+    glTexCoordPointer, glTexImage2D, glTexParameterf,
+    glTexParameteri, glTranslatef, glVertex2d, glVertexPointer,
+    glViewport, glext_LoadExtension, glDeleteRenderbuffersEXT,
+    glDeleteFramebuffersEXT, glGenFramebuffersEXT,
+    glGenRenderbuffersEXT, glBindFramebufferEXT, 
+    glBindRenderbufferEXT, glRenderbufferStorageEXT,
+    glFramebufferRenderbufferEXT, glFramebufferTexture2DEXT,
+    glUniformMatrix4fv, glVertexAttribPointer, glCreateShader,
+    glShaderSource, glCompileShader, glGetShaderiv, glGetShaderInfoLog,
+    glCreateProgram, glAttachShader, glBindAttribLocation, glLinkProgram,
+    glDeleteShader, glGetProgramiv, glGetProgramInfoLog, glUseProgram,
+    glUniform1i, glGetUniformLocation, glEnableVertexAttribArray,
+    glGetError, glDeleteProgram, glDeleteBuffers,
+    glGenBuffers, glBufferData, glBindBuffer, glewInit,
+    glUniform4f, glDisableVertexAttribArray : procedure;
+
+    GL_BGRA, GL_BLEND, GL_CLAMP_TO_EDGE, GL_COLOR_ARRAY,
+    GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_DEPTH_COMPONENT,
+    GL_DITHER, GL_EXTENSIONS, GL_FALSE, GL_FASTEST, GL_LINEAR,
+    GL_LINE_LOOP, GL_LINES, GL_LINE_SMOOTH, GL_LINE_STRIP,
+    GL_MAX_TEXTURE_SIZE, GL_MODELVIEW, GL_ONE_MINUS_SRC_ALPHA,
+    GL_PERSPECTIVE_CORRECTION_HINT, GL_PROJECTION, GL_QUADS,
+    GL_RENDERER, GL_RGBA, GL_RGBA8, GL_SRC_ALPHA, GL_TEXTURE_2D,
+    GL_TEXTURE_COORD_ARRAY, GL_TEXTURE_MAG_FILTER,
+    GL_TEXTURE_MIN_FILTER, GL_TEXTURE_PRIORITY, GL_TEXTURE_WRAP_S,
+    GL_TEXTURE_WRAP_T, GL_TRIANGLE_FAN, GL_TRUE, GL_VENDOR,
+    GL_VERSION, GL_VERTEX_ARRAY, GLenum,  GL_FRAMEBUFFER_EXT,
+    GL_RENDERBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
+    GL_COLOR_ATTACHMENT0_EXT, GL_FLOAT, GL_UNSIGNED_BYTE, GL_COMPILE_STATUS,
+    GL_INFO_LOG_LENGTH, GL_LINK_STATUS, GL_VERTEX_SHADER, GL_FRAGMENT_SHADER,
+    GL_NO_ERROR, GL_ARRAY_BUFFER, GL_STATIC_DRAW, GLEW_OK,
+    GL_AUX_BUFFERS: integer;
+
+    TThreadId : function : integer;
+    
+    _strconcat, _strappend, _strprepend, _chrconcat : function : string;
+    _strcompare, _strncompare, _strcomparec : function : boolean;
+
+    png_structp, png_set_write_fn, png_get_io_ptr,
+    png_get_libpng_ver, png_create_write_struct,
+    png_create_info_struct, png_destroy_write_struct,
+    png_write_row, png_set_ihdr, png_write_info,
+    png_write_end : procedure;
+
+    clear_filelist_hook, add_file_hook, idb_loader_hook, mainloop_hook, drawworld_hook : procedure;
+    SDL_InitPatch : procedure;
+
+  
Binary file hedgewars/res/hwengine.ico has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/res/hwengine.rc	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,1 @@
+MAINICON ICON "res/hwengine.ico"
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/sdlmain_osx/CMakeLists.txt	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,8 @@
+if(APPLE)
+    #let's look for the installed sdlmain file; if it is not found, let's build our own
+    find_package(SDL REQUIRED)
+
+    include_directories(${SDL_INCLUDE_DIR})
+    add_library (SDLmain STATIC ${CMAKE_CURRENT_SOURCE_DIR}/SDLMain.m)
+endif(APPLE)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/sdlmain_osx/SDLMain.h	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,16 @@
+/*   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_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/sdlmain_osx/SDLMain.m	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,385 @@
+/*   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	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uAI.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -33,6 +33,11 @@
     uAmmos, SysUtils, uTypes,
     uVariables, uCommands, uUtils, uDebug, uAILandMarks;
 
+{$IFDEF AI_MAINTHREAD}
+const
+    mainThreadMaxThinkTime:Integer = 1500;
+{$ENDIF}
+
 var BestActions: TActions;
     CanUseAmmo: array [TAmmoType] of boolean;
     StopThinking: boolean;
@@ -351,6 +356,15 @@
 
             if GoInfo.FallPix >= FallPixForBranching then
                 Push(ticks, Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right
+
+{$IFDEF AI_MAINTHREAD}
+            if StartTicks < (SDL_GetTicks() - mainThreadMaxThinkTime) then
+                StopThinking := true;
+{$ELSE}
+            if (StartTicks > GameTicks - 1500) and (not StopThinking) then
+                SDL_Delay(1000);
+{$ENDIF}
+
             end {while};
 
         if BestRate > BaseRate then
@@ -362,12 +376,13 @@
 function Think(Me: PGear): LongInt; cdecl; export;
 var BackMe, WalkMe: TGear;
     switchCount: LongInt;
-    StartTicks, currHedgehogIndex, itHedgehog, switchesNum, i: Longword;
+    currHedgehogIndex, itHedgehog, switchesNum, i: Longword;
     switchImmediatelyAvailable: boolean;
     Actions: TActions;
 begin
 dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent;
 StartTicks:= GameTicks;
+
 currHedgehogIndex:= CurrentTeam^.CurrHedgehog;
 itHedgehog:= currHedgehogIndex;
 switchesNum:= 0;
@@ -389,7 +404,7 @@
             Actions.Score:= 0;
             if switchesNum > 0 then
                 begin
-                if not switchImmediatelyAvailable  then
+                if (not switchImmediatelyAvailable)  then
                     begin
                     // when AI has to use switcher, make it cost smth unless they have a lot of switches
                     if (switchCount < 10) then Actions.Score:= (-27+switchCount*3)*4000;
@@ -413,8 +428,13 @@
             or (itHedgehog = currHedgehogIndex)
             or BestActions.isWalkingToABetterPlace;
 
-        if (StartTicks > GameTicks - 1500) and (not StopThinking) then
-            SDL_Delay(1000);
+            {$IFDEF AI_MAINTHREAD}
+                if StartTicks < (SDL_GetTicks() - mainThreadMaxThinkTime) then
+                    StopThinking := true;
+            {$ELSE}
+                if (StartTicks > GameTicks - 1500) and (not StopThinking) then
+                    SDL_Delay(1000);
+            {$ENDIF}
 
         if (BestActions.Score < -1023) and (not BestActions.isWalkingToABetterPlace) then
             begin
@@ -429,11 +449,13 @@
     i:= 12;
     while (not StopThinking) and (BestActions.Count = 0) and (i > 0) do
         begin
+
 (*
         // Maybe this would get a bit of movement out of them? Hopefully not *toward* water. Need to check how often he'd choose that strategy
         if SuddenDeathDmg and ((hwRound(BackMe.Y)+cWaterRise*2) > cWaterLine) then
             AddBonus(hwRound(BackMe.X), hwRound(BackMe.Y), 250, -40);
 *)
+
         FillBonuses(true);
         WalkMe:= BackMe;
         Actions.Count:= 0;
--- a/hedgewars/uAIAmmoTests.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uAIAmmoTests.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -244,7 +244,7 @@
                     or (y < 0)
                     or (trunc(x) > LAND_WIDTH)
                     or (trunc(y) > LAND_HEIGHT)
-                    or not TestCollExcludingObjects(trunc(x), trunc(y), 5)
+                    or (not TestCollExcludingObjects(trunc(x), trunc(y), 5))
                     or (timer = 0)
                 end;
             EX:= trunc(x);
@@ -771,7 +771,7 @@
     Targ:= Targ; // avoid compiler hint
 
     if Level < 3 then trackFall:= afTrackFall
-    else trackFall:= 0;
+        else trackFall:= 0;
 
     ap.ExplR:= 0;
     ap.Time:= 0;
--- a/hedgewars/uAIMisc.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uAIMisc.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -53,7 +53,17 @@
     X, Y: LongInt;
     Radius: LongInt;
     Score: LongInt;
-    end;
+	 end;
+
+Tbonuses = record
+	      Count : Longword;
+	      ar    : array[0..Pred(MAXBONUS)] of TBonus;
+	   end;
+
+Twalkbonuses =  record
+        Count: Longword;
+        ar: array[0..Pred(MAXBONUS div 8)] of TBonus;  // don't use too many
+        end;
 
 procedure initModule;
 procedure freeModule;
@@ -82,15 +92,9 @@
 var ThinkingHH: PGear;
     Targets: TTargets;
 
-    bonuses: record
-        Count: Longword;
-        ar: array[0..Pred(MAXBONUS)] of TBonus;
-        end;
+    bonuses: Tbonuses;
 
-    walkbonuses: record
-        Count: Longword;
-        ar: array[0..Pred(MAXBONUS div 8)] of TBonus;  // don't use too many
-        end;
+    walkbonuses: Twalkbonuses;
 
 const KillScore = 200;
 var friendlyfactor: LongInt = 300;
@@ -127,7 +131,7 @@
     if  (((Gear^.Kind = gtHedgehog) and
             (Gear <> ThinkingHH) and
             (Gear^.Health > Gear^.Damage) and
-            not(Gear^.Hedgehog^.Team^.hasgone)) or
+            (not Gear^.Hedgehog^.Team^.hasgone)) or
         ((Gear^.Kind = gtExplosives) and
             (Gear^.Health > Gear^.Damage)) or
         ((Gear^.Kind = gtMine) and
@@ -397,7 +401,7 @@
                         dmg := trunc(dxdy * 25);
                         exit(dmg)
                         end
-                    else if (Kind = gtExplosives) and not((abs(odX) > 0.15) or ((abs(odY) > 0.15) and (abs(odX) > 0.02))) and (dY > 0.2) then
+                    else if (Kind = gtExplosives) and (not(abs(odX) > 0.15) or ((abs(odY) > 0.15) and (abs(odX) > 0.02))) and (dY > 0.2) then
                         begin
                         dmg := trunc(dy * 70);
                         exit(dmg)
@@ -449,7 +453,7 @@
                         dmg := trunc(dxdy * 50);
                         exit(dmg)
                         end
-                    else if (Kind = gtExplosives) and not((abs(odX) > 0.15) or ((abs(odY) > 0.15) and (abs(odX) > 0.02))) and (dY > 0.2) then
+                    else if (Kind = gtExplosives) and (not(abs(odX) > 0.15) or ((abs(odY) > 0.15) and (abs(odX) > 0.02))) and (dY > 0.2) then
                         begin
                         dmg := trunc(dy * 70);
                         exit(dmg)
@@ -606,7 +610,7 @@
                 pY:= Point.y-2;
                 fallDmg:= 0;
                 if (Flags and afSetSkip <> 0) then skip:= true;
-                if not(dead) and (Flags and afTrackFall <> 0) and (Score > 0) and (power < Score) then
+                if (not dead) and (Flags and afTrackFall <> 0) and (Score > 0) and (power < Score) then
                     if (Kind = gtExplosives) and (State and gstTmpFlag = 0) and 
                        (((abs(dY) > 0.15) and (abs(dX) < 0.02)) or
                         ((abs(dY) < 0.15) and (abs(dX) < 0.15))) then
@@ -701,7 +705,7 @@
                 end;
             if dmg > 0 then
                 begin
-                if not(dead) and (Score > 0) and (dmg < Score) then
+                if (not dead) and (Score > 0) and (dmg < Score) then
                     begin
                     pX:= Point.x;
                     pY:= Point.y;
--- a/hedgewars/uAmmos.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uAmmos.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -257,7 +257,7 @@
             Ammo^[Slot, ami]:= Ammo^[Slot, ami + 1];
             Ammo^[Slot, ami + 1].Count:= 0
             end;
-    until not b;
+    until (not b);
 AmmoMenuInvalidated:= true;
 end;
 
--- a/hedgewars/uCaptions.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uCaptions.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -45,6 +45,8 @@
 procedure AddCaption(s: shortstring; Color: Longword; Group: TCapGroup);
 begin
     if cOnlyStats then exit;
+    if Length(s) = 0 then
+        exit;
     if Captions[Group].Text <> s then
         begin
         FreeTexture(Captions[Group].Tex);
--- a/hedgewars/uChat.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uChat.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -41,7 +41,7 @@
     Width: LongInt;
     s: shortstring;
     end;
-    TChatCmd = (quit, pause, finish, fullscreen);
+    TChatCmd = (quitCmd, pauseCmd, finishCmd, fullscreenCmd);
 
 var Strs: array[0 .. MaxStrIndex] of TChatLine;
     MStrs: array[0 .. MaxStrIndex] of shortstring;
@@ -226,7 +226,7 @@
 else if (s[1] = '-') and (s[Length(s)] = '-') then
     x:= 3;
 
-if not CurrentTeam^.ExtDriven and (x <> 0) then
+if (not CurrentTeam^.ExtDriven) and (x <> 0) then
     for c:= 0 to Pred(TeamsCount) do
         if (TeamsArray[c] = CurrentTeam) then
             t:= c;
--- a/hedgewars/uCommandHandlers.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uCommandHandlers.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -187,37 +187,37 @@
 
 procedure chCurD_m(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 CursorMovementY:= 0;
 end;
 
 procedure chCurL_p(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 CursorMovementX:= -1;
 end;
 
 procedure chCurL_m(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 CursorMovementX:= 0;
 end;
 
 procedure chCurR_p(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 CursorMovementX:= 1;
 end;
 
 procedure chCurR_m(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 CursorMovementX:= 0;
 end;
 
 procedure chLeft_p(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 if CheckNoTeamOrHH or isPaused then
     exit;
 if not isExternalSource then
@@ -230,7 +230,7 @@
 
 procedure chLeft_m(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 if CheckNoTeamOrHH then
     exit;
 if not isExternalSource then
@@ -242,7 +242,7 @@
 
 procedure chRight_p(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 if CheckNoTeamOrHH or isPaused then
     exit;
 if not isExternalSource then
@@ -255,7 +255,7 @@
 
 procedure chRight_m(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 if CheckNoTeamOrHH then
     exit;
 if not isExternalSource then
@@ -267,7 +267,7 @@
 
 procedure chUp_p(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 if CheckNoTeamOrHH or isPaused then
     exit;
 if not isExternalSource then
@@ -280,7 +280,7 @@
 
 procedure chUp_m(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 if CheckNoTeamOrHH then
     exit;
 if not isExternalSource then
@@ -292,7 +292,7 @@
 
 procedure chDown_p(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 if CheckNoTeamOrHH or isPaused then
     exit;
 if not isExternalSource then
@@ -305,7 +305,7 @@
 
 procedure chDown_m(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 if CheckNoTeamOrHH then
     exit;
 if not isExternalSource then
@@ -317,7 +317,7 @@
 
 procedure chPrecise_p(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 if CheckNoTeamOrHH or isPaused then
     exit;
 if not isExternalSource then
@@ -330,7 +330,7 @@
 
 procedure chPrecise_m(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 if CheckNoTeamOrHH then
     exit;
 if not isExternalSource then
@@ -342,7 +342,7 @@
 
 procedure chLJump(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 if CheckNoTeamOrHH or isPaused then
     exit;
 if not isExternalSource then
@@ -355,7 +355,7 @@
 
 procedure chHJump(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 if CheckNoTeamOrHH or isPaused then
     exit;
 if not isExternalSource then
@@ -368,7 +368,7 @@
 
 procedure chAttack_p(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 if CheckNoTeamOrHH or isPaused then
     exit;
 bShowFinger:= false;
@@ -388,7 +388,7 @@
 
 procedure chAttack_m(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 if CheckNoTeamOrHH then
     exit;
 with CurrentHedgehog^.Gear^ do
@@ -403,7 +403,7 @@
 
 procedure chSwitch(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 if CheckNoTeamOrHH or isPaused then
     exit;
 if not isExternalSource then
@@ -415,9 +415,10 @@
 end;
 
 procedure chNextTurn(var s: shortstring);
-var gi: PGear;
+var i  : Longword;
+    gi : PGear;
 begin
-    s:= s; // avoid compiler hint
+    s:=s; // avoid compiler hint
 
     TryDo(AllInactive, '/nextturn called when not all gears are inactive', true);
 
@@ -524,13 +525,13 @@
 
 procedure chPut(var s: shortstring);
 begin
-    s:= s; // avoid compiler hint
+    s:=s; // avoid compiler hint
     doPut(0, 0, false);
 end;
 
 procedure chCapture(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 flagMakeCapture:= true
 end;
 
@@ -581,7 +582,7 @@
 
 procedure chAmmoMenu(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 if CheckNoTeamOrHH then
     bShowAmmoMenu:= true
 else
@@ -605,19 +606,19 @@
 
 procedure chVol_p(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 inc(cVolumeDelta, 3)
 end;
 
 procedure chVol_m(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 dec(cVolumeDelta, 3)
 end;
 
 procedure chFindhh(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 if CheckNoTeamOrHH or isPaused then
     exit;
 
@@ -639,7 +640,7 @@
 
 procedure chPause(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 if gameType <> gmtNet then
     isPaused:= not isPaused;
 
@@ -651,7 +652,7 @@
 
 procedure chRotateMask(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 if ((GameFlags and gfInvulnerable) = 0) then
     cTagsMask:= cTagsMasks[cTagsMask]
 else
@@ -660,34 +661,34 @@
 
 procedure chSpeedup_p(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 SpeedStart:= RealTicks;
 isSpeed:= true
 end;
 
 procedure chSpeedup_m(var s: shortstring);
 begin
-s:= s; // avoid compiler hint
+s:=s; // avoid compiler hint
 isSpeed:= false
 end;
 
 procedure chZoomIn(var s: shortstring);
 begin
-    s:= s; // avoid compiler hint
+    s:=s; // avoid compiler hint
     if ZoomValue < cMinZoomLevel then
         ZoomValue:= ZoomValue + cZoomDelta;
 end;
 
 procedure chZoomOut(var s: shortstring);
 begin
-    s:= s; // avoid compiler hint
+    s:=s; // avoid compiler hint
     if ZoomValue > cMaxZoomLevel then
         ZoomValue:= ZoomValue - cZoomDelta;
 end;
 
 procedure chZoomReset(var s: shortstring);
 begin
-    s:= s; // avoid compiler hint
+    s:=s; // avoid compiler hint
     ZoomValue:= cDefaultZoomLevel;
 end;
 
--- a/hedgewars/uConsts.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uConsts.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -93,7 +93,7 @@
 // lfObject and lfBasic are only to be different *graphically*  in all other ways they should be treated the same
     lfBasic          = $8000;  // white
     lfIndestructible = $4000;  // red
-    lfObject         = $2000;  
+    lfObject         = $2000;
     lfDamaged        = $1000;  //
     lfIce            = $0800;  // blue
     lfBouncy         = $0400;  // green
@@ -115,11 +115,13 @@
     MAXNAMELEN = 192;
     MAXROPEPOINTS = 3840;
 
+    {$IFNDEF PAS2C}
     // some opengl headers do not have these macros
     GL_BGR              = $80E0;
     GL_BGRA             = $80E1;
     GL_CLAMP_TO_EDGE    = $812F;
     GL_TEXTURE_PRIORITY = $8066;
+    {$ENDIF}
 
     cVisibleWater       : LongInt = 128;
     cTeamHealthWidth    : LongInt = 128;
@@ -150,7 +152,7 @@
     cBlowTorchC    = 6;
     cakeDmg =   75;
 
-    cKeyMaxIndex = 1023;
+    cKeyMaxIndex = 1600;
     cKbdMaxIndex = 65536;//need more room for the modifier keys
 
     cFontBorder = 2;
@@ -238,11 +240,11 @@
 
     cMaxSlotIndex       = 9;
     cMaxSlotAmmoIndex   = 5;
-    
+
     // ai hints
     aihUsualProcessing    = $00000000;
     aihDoesntMatter       = $00000001;
-    
+
     // ammo properties
     ammoprop_Timerable    = $00000001;
     ammoprop_Power        = $00000002;
@@ -258,7 +260,7 @@
     ammoprop_Utility      = $00001000;
     ammoprop_Effect       = $00002000;
     ammoprop_SetBounce    = $00004000;
-    ammoprop_NeedUpDown   = $00008000;//Used by TouchInterface to show or hide up/down widgets 
+    ammoprop_NeedUpDown   = $00008000;//Used by TouchInterface to show or hide up/down widgets
     ammoprop_OscAim       = $00010000;
     ammoprop_NoMoveAfter  = $00020000;
     ammoprop_Track        = $00040000;
--- a/hedgewars/uCursor.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uCursor.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -11,6 +11,10 @@
 
 uses SDLh, uVariables;
 
+{$IFDEF WEBGL}
+var offsetx, offsety : Integer;
+{$ENDIF}
+
 procedure init;
 begin
     resetPosition();
@@ -23,16 +27,33 @@
 
 procedure updatePosition;
 var x, y: LongInt;
+{$IFDEF WEBGL}
+    tx, ty : LongInt;
+{$ENDIF}
 begin
     SDL_GetMouseState(@x, @y);
-    
+
+{$IFDEF WEBGL}
+    tx := x;
+    ty := y;
+    x := x + offsetx;
+    y := y + offsety;
+{$ENDIF}
+
     if(x <> cScreenWidth div 2) or (y <> cScreenHeight div 2) then
     begin
         handlePositionUpdate(x - cScreenWidth div 2, y - cScreenHeight div 2);
 
         if cHasFocus then
+            begin
+            {$IFNDEF WEBGL}
             SDL_WarpMouse(cScreenWidth div 2, cScreenHeight div 2);
-    end
+            {$ELSE}
+            offsetx := cScreenWidth div 2 - tx;
+            offsety := cScreenHeight div 2 - ty;
+            {$ENDIF}
+            end;
+        end
 end;
 
 procedure handlePositionUpdate(x, y: LongInt);
--- a/hedgewars/uFloat.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uFloat.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -55,7 +55,7 @@
     1: (QWordValue : QWord);
     end;
 {$ENDIF}
-
+		  
 // Returns an hwFloat that represents the value of integer parameter i
 function int2hwFloat (const i: LongInt) : hwFloat; inline;
 function hwFloat2Float (const i: hwFloat) : extended; inline;
@@ -63,7 +63,9 @@
 // The implemented operators
 
 operator = (const z1, z2: hwFloat) z : boolean; inline;
-
+{$IFDEF PAS2C}
+operator <> (const z1, z2: hwFloat) z : boolean; inline;
+{$ENDIF}
 operator + (const z1, z2: hwFloat) z : hwFloat; inline;
 operator - (const z1, z2: hwFloat) z : hwFloat; inline;
 operator - (const z1: hwFloat) z : hwFloat; inline;
@@ -220,11 +222,19 @@
     hwFloat2Float:= -hwFloat2Float;
 end;
 
+{$IFNDEF WEBGL}
 operator = (const z1, z2: hwFloat) z : boolean; inline;
 begin
     z:= (z1.isNegative = z2.isNegative) and (z1.QWordValue = z2.QWordValue);
 end;
 
+{$IFDEF PAS2C}
+operator <> (const z1, z2: hwFloat) z : boolean; inline;
+begin
+    z:= (z1.isNegative <> z2.isNegative) or (z1.QWordValue <> z2.QWordValue);
+end;
+{$ENDIF}
+
 operator + (const z1, z2: hwFloat) z : hwFloat; inline;
 begin
 if z1.isNegative = z2.isNegative then
@@ -291,6 +301,102 @@
     else
         b:= (z1.QWordValue > z2.QWordValue) <> z2.isNegative
 end;
+{$ENDIF}
+{$IFDEF WEBGL}
+(*
+    Mostly to be kind to JS as of 2012-08-27 where there is no int64/uint64.  This may change though.
+*)
+operator = (const z1, z2: hwFloat) z : boolean; inline;
+begin
+    z:= (z1.isNegative = z2.isNegative) and (z1.Frac = z2.Frac) and (z1.Round = z2.Round);
+end;
+
+operator <> (const z1, z2: hwFloat) z : boolean; inline;
+begin
+    z:= (z1.isNegative <> z2.isNegative) or (z1.Frac <> z2.Frac) or (z1.Round <> z2.Round);
+end;
+
+operator + (const z1, z2: hwFloat) z : hwFloat; inline;
+begin
+if z1.isNegative = z2.isNegative then
+    begin
+    z:= z1;
+    z.Frac:= z.Frac + z2.Frac;
+    z.Round:= z.Round + z2.Round;
+    if z.Frac<z1.Frac then inc(z.Round)
+    end
+else
+    if (z1.Round > z2.Round) or ((z1.Round = z2.Round) and (z1.Frac > z2.Frac)) then
+        begin
+        z.isNegative:= z1.isNegative;
+        z.Round:= z1.Round - z2.Round;
+        z.Frac:= z1.Frac - z2.Frac;
+        if z2.Frac > z1.Frac then dec(z.Round)
+        end
+    else
+        begin
+        z.isNegative:= z2.isNegative;
+        z.Round:= z2.Round - z1.Round;
+        z.Frac:= z2.Frac-z1.Frac;
+        if z2.Frac < z1.Frac then dec(z.Round)
+        end
+end;
+
+operator - (const z1, z2: hwFloat) z : hwFloat; inline;
+begin
+if z1.isNegative = z2.isNegative then
+    if (z1.Round > z2.Round) or ((z1.Round = z2.Round) and (z1.Frac > z2.Frac)) then
+        begin
+        z.isNegative:= z1.isNegative;
+        z.Round:= z1.Round - z2.Round;
+        z.Frac:= z1.Frac-z2.Frac;
+        if z2.Frac > z1.Frac then dec(z.Round)
+        end
+    else
+        begin
+        z.isNegative:= not z2.isNegative;
+        z.Round:= z2.Round - z1.Round;
+        z.Frac:= z2.Frac-z1.Frac;
+        if z2.Frac < z1.Frac then dec(z.Round)
+        end
+else
+    begin
+    z:= z1;
+    z.Frac:= z.Frac + z2.Frac;
+    z.Round:= z.Round + z2.Round;
+    if z.Frac<z1.Frac then inc(z.Round)
+    end
+end;
+
+operator < (const z1, z2: hwFloat) b : boolean; inline;
+begin
+if z1.isNegative xor z2.isNegative then
+    b:= z1.isNegative
+else
+(*  Not so sure this specialcase is a win w/ Round/Frac. have to do more tests anyway.
+    if (z1.Round = z2.Round and (z1.Frac = z2.Frac)) then
+        b:= false
+    else *)
+        b:= ((z1.Round < z2.Round) or ((z1.Round = z2.Round) and (z1.Frac < z2.Frac))) <> z1.isNegative
+end;
+
+operator > (const z1, z2: hwFloat) b : boolean; inline;
+begin
+if z1.isNegative xor z2.isNegative then
+    b:= z2.isNegative
+else
+(*
+    if z1.QWordValue = z2.QWordValue then
+        b:= false
+    else*)
+        b:= ((z1.Round > z2.Round) or ((z1.Round = z2.Round) and (z1.Frac > z2.Frac))) <> z1.isNegative
+end;
+
+function isZero(const z: hwFloat): boolean; inline; 
+begin
+isZero := (z.Round = 0) and (z.Frac = 0);
+end;
+{$ENDIF}
 
 operator - (const z1: hwFloat) z : hwFloat; inline;
 begin
--- a/hedgewars/uGame.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uGame.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -26,7 +26,8 @@
 ////////////////////
     implementation
 ////////////////////
-uses uInputHandler, uTeams, uIO, uAI, uGears, uSound, uLocale, uCaptions,
+uses uInputHandler, uTeams, uIO, uAI, uGears, uSound,
+    uLocale, uCaptions,
     uVisualGears, uTypes, uVariables, uCommands, uConsts
     {$IFDEF USE_TOUCH_INTERFACE}, uTouch{$ENDIF};
 
@@ -51,7 +52,7 @@
     else if (GameType = gmtSave) or (fastUntilLag and (GameType = gmtNet)) then
         Lag:= 2500;
 
-    if (GameType = gmtDemo) then 
+    if (GameType = gmtDemo) then
         if isSpeed then
             begin
             i:= RealTicks-SpeedStart;
@@ -116,9 +117,10 @@
                         AddVisualGear(0, 0, vgtTeamHealthSorter);
                         AddVisualGear(0, 0, vgtSmoothWindBar);
                         {$IFDEF IPHONEOS}InitIPC;{$ENDIF}
-                        with mobileRecord do
+                        {$IFNDEF PAS2C}with mobileRecord do
                             if SaveLoadingEnded <> nil then
                                 SaveLoadingEnded();
+                        {$ENDIF}
                         end;
                 end
         else ProcessGears
--- a/hedgewars/uGears.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uGears.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -46,7 +46,6 @@
 procedure ProcessGears;
 procedure EndTurnCleanup;
 procedure SetAllToActive;
-procedure SetAllHHToActive; inline;
 procedure SetAllHHToActive(Ice: boolean);
 procedure DrawGears;
 procedure FreeGearsList;
@@ -55,7 +54,6 @@
 function  GearByUID(uid : Longword) : PGear;
 procedure doStepDrowningGear(Gear: PGear);
 
-
 implementation
 uses uStore, uSound, uTeams, uRandom, uCollisions, uIO, uLandGraphics, {$IFDEF SDL13}uTouch,{$ENDIF}
     uLocale, uAI, uAmmos, uStats, uVisualGears, uScript, GLunit, uVariables,
@@ -101,7 +99,7 @@
         begin
         if (not isInMultiShoot) then
             inc(Gear^.Damage, Gear^.Karma);
-        if (Gear^.Damage <> 0) and (not Gear^.Invulnerable) then
+        if ((Gear^.Damage <> 0) and (not Gear^.Invulnerable)) then
             begin
             CheckNoDamage:= false;
 
@@ -168,14 +166,14 @@
                     if (team^.Hedgehogs[i].Gear <> nil) and (not team^.Hedgehogs[i].King)
                     and (team^.Hedgehogs[i].Gear^.Health > team^.Hedgehogs[i].Gear^.Damage) then
                         flag:= true;
-                if not flag then
+                if (not flag) then
                     begin
                     inc(tmp, 5);
                     if (GameFlags and gfResetHealth) <> 0 then
                         dec(Gear^.Hedgehog^.InitialHealth, 5)
                     end
                 end;
-            if tmp > 0 then 
+            if tmp > 0 then
                 begin
                 inc(Gear^.Damage, min(tmp, max(0,Gear^.Health - 1 - Gear^.Damage)));
                 HHHurt(Gear^.Hedgehog, dsPoison);
@@ -225,12 +223,12 @@
         DeleteGear(curHandledGear)
     else
         begin
-        if curHandledGear^.Message and gmRemoveFromList <> 0 then 
+        if curHandledGear^.Message and gmRemoveFromList <> 0 then
             begin
             RemoveGearFromList(curHandledGear);
             // since I can't think of any good reason this would ever be separate from a remove from list, going to keep it inside this block
             if curHandledGear^.Message and gmAddToList <> 0 then InsertGearToList(curHandledGear);
-            curHandledGear^.Message:= curHandledGear^.Message and (not (gmRemoveFromList or gmAddToList))
+            curHandledGear^.Message:= (curHandledGear^.Message and (not (gmRemoveFromList or gmAddToList)))
             end;
         if curHandledGear^.Active then
             begin
@@ -259,13 +257,13 @@
         if delay = 0 then
             inc(step)
         end;
-        
+
     stChDmg:
     if CheckNoDamage then
         inc(step)
     else
         step:= stDelay;
-        
+
     stSweep:
     if SweepDirty then
         begin
@@ -274,7 +272,7 @@
         end
     else
         inc(step);
-        
+
     stTurnReact:
         begin
         if (not bBetweenTurns) and (not isInMultiShoot) then
@@ -285,7 +283,7 @@
         else
             inc(step, 2);
         end;
-        
+
     stAfterDelay:
         begin
         if delay = 0 then
@@ -328,12 +326,12 @@
                 if cHealthDecrease <> 0 then
                     begin
                     SuddenDeathDmg:= true;
-                        
+
                     // flash
                     ScreenFade:= sfFromWhite;
                     ScreenFadeValue:= sfMax;
                     ScreenFadeSpeed:= 1;
-                    
+
                     ChangeToSDClouds;
                     ChangeToSDFlakes;
                     glClearColor(SDSkyColor.r * (SDTint/255) / 255, SDSkyColor.g * (SDTint/255) / 255, SDSkyColor.b * (SDTint/255) / 255, 0.99);
@@ -345,7 +343,7 @@
                 StopMusic //No SDMusic for now
                     //ChangeMusic(SDMusic)
                     end
-                else if (TotalRounds < cSuddenDTurns) and (not isInMultiShoot) then
+                else if ((TotalRounds < cSuddenDTurns) and (not isInMultiShoot)) then
                     begin
                     i:= cSuddenDTurns - TotalRounds;
                     s:= inttostr(i);
@@ -368,7 +366,7 @@
             end;
     stSpawn:
         begin
-        if not isInMultiShoot then
+        if (not isInMultiShoot) then
             SpawnBoxOfSmth;
         inc(step)
         end;
@@ -418,7 +416,7 @@
                 CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State or gstHHChooseTarget;
                 isCursorVisible := true
                 end;
-            CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State and (not gstAttacked);
+            CurrentHedgehog^.Gear^.State:= (CurrentHedgehog^.Gear^.State and (not gstAttacked));
             end;
         if delay2 = 0 then
             begin
@@ -444,7 +442,7 @@
 if TurnTimeLeft > 0 then
     if CurrentHedgehog^.Gear <> nil then
         if ((CurrentHedgehog^.Gear^.State and gstAttacking) = 0) and 
-            not(isInMultiShoot and (CurrentHedgehog^.CurAmmoType in [amShotgun, amDEagle, amSniperRifle])) then
+            (not (isInMultiShoot and (CurrentHedgehog^.CurAmmoType in [amShotgun, amDEagle, amSniperRifle]))) then
                 begin
                 if (TurnTimeLeft = 5000)
                 and (cHedgehogTurnTime >= 10000)
@@ -542,7 +540,7 @@
             end;
         t:= t^.NextGear
         end;
-   
+
     if ((GameFlags and gfResetWeps) <> 0) and (not PlacingHogs) then
         ResetWeapons;
 
@@ -563,11 +561,6 @@
     end
 end;
 
-procedure SetAllHHToActive; inline;
-begin
-SetAllHHToActive(true)
-end;
-
 procedure SetAllHHToActive(Ice: boolean);
 var t: PGear;
 begin
@@ -618,6 +611,7 @@
 var i,rx, ry: Longword;
     rdx, rdy: hwFloat;
     Gear: PGear;
+    temp: Longword;
 begin
 AddGear(0, 0, gtATStartGame, 0, _0, _0, 2000);
 
@@ -720,7 +714,7 @@
                         t^.dX:= t^.dX + Gear^.dX * dmg * _0_01 + SignAs(cHHKick, Gear^.dX);
                         t^.dY:= t^.dY + Gear^.dY * dmg * _0_01;
                         t^.State:= t^.State or gstMoving;
-                        if t^.Kind = gtKnife then t^.State:= t^.State and (not gstCollision);
+                        if t^.Kind = gtKnife then t^.State:= (t^.State and (not gstCollision));
                         t^.Active:= true;
                         FollowGear:= t
                         end
@@ -781,7 +775,7 @@
     if (Gear^.State and gstNoDamage) = 0 then
         begin
 
-        if (Ammo^.Kind = gtDEagleShot) or (Ammo^.Kind = gtSniperRifleShot) then 
+        if (Ammo^.Kind = gtDEagleShot) or (Ammo^.Kind = gtSniperRifleShot) then
             begin
             VGear := AddVisualGear(hwround(Ammo^.X), hwround(Ammo^.Y), vgtBulletHit);
             if VGear <> nil then
@@ -832,10 +826,10 @@
                 end
             else
                 Gear^.State:= Gear^.State or gstWinner;
-            if (Gear^.Kind = gtExplosives) and (Ammo^.Kind = gtBlowtorch) then 
+            if (Gear^.Kind = gtExplosives) and (Ammo^.Kind = gtBlowtorch) then
                 begin
                 if (Ammo^.Hedgehog^.Gear <> nil) then
-                    Ammo^.Hedgehog^.Gear^.State:= Ammo^.Hedgehog^.Gear^.State and (not gstNotKickable);
+                    Ammo^.Hedgehog^.Gear^.State:= (Ammo^.Hedgehog^.Gear^.State and (not gstNotKickable));
                 ApplyDamage(Gear, Ammo^.Hedgehog, tmpDmg * 100, dsUnknown); // crank up damage for explosives + blowtorch
                 end;
 
@@ -855,17 +849,17 @@
                 Gear^.Active:= true;
                 DeleteCI(Gear);
                 Gear^.State:= Gear^.State or gstMoving;
-                if Gear^.Kind = gtKnife then Gear^.State:= Gear^.State and (not gstCollision);
+                if Gear^.Kind = gtKnife then Gear^.State:= (Gear^.State and (not gstCollision));
                 // move the gear upwards a bit to throw it over tiny obstacles at start
                 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then
                     begin
-                    if not (TestCollisionXwithXYShift(Gear, _0, -3, hwSign(Gear^.dX))
+                    if (not (TestCollisionXwithXYShift(Gear, _0, -3, hwSign(Gear^.dX)))
                     or (TestCollisionYwithGear(Gear, -1) <> 0)) then
                         Gear^.Y:= Gear^.Y - _1;
-                    if not (TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX))
+                    if (not (TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)))
                     or (TestCollisionYwithGear(Gear, -1) <> 0)) then
                         Gear^.Y:= Gear^.Y - _1;
-                    if not (TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX))
+                    if (not (TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)))
                     or (TestCollisionYwithGear(Gear, -1) <> 0)) then
                         Gear^.Y:= Gear^.Y - _1;
                     end
@@ -956,9 +950,9 @@
     s:= 0;
     SetLength(GearsNearArray, s);
     t := GearsList;
-    while t <> nil do 
+    while t <> nil do
         begin
-        if (t^.Kind = Kind) 
+        if (t^.Kind = Kind)
             and ((X - t^.X)*(X - t^.X) + (Y - t^.Y)*(Y-t^.Y) < int2hwFloat(r)) then
             begin
             inc(s);
@@ -979,7 +973,7 @@
 while t <> nil do
     begin
     if (t^.Kind = gtHedgehog) and (t^.Y < Ammo^.Y) then
-        if not (hwSqr(Ammo^.X - t^.X) + hwSqr(Ammo^.Y - t^.Y - int2hwFloat(cHHRadius)) * 2 > _2) then
+        if (not (hwSqr(Ammo^.X - t^.X) + hwSqr(Ammo^.Y - t^.Y - int2hwFloat(cHHRadius)) * 2 > _2)) then
             begin
             ApplyDamage(t, 5);
             t^.dX:= t^.dX + (t^.X - Ammo^.X) * _0_02;
@@ -1050,7 +1044,7 @@
     FollowGear := AddGear(x, y, gtCase, 0, _0, _0, 0);
     cCaseFactor := 0;
     FollowGear^.Pos := posCaseDummy;
-    
+
     if explode then
         FollowGear^.Pos := FollowGear^.Pos + posCaseExplode;
     if poison then
@@ -1244,7 +1238,7 @@
 procedure chSkip(var s: shortstring);
 begin
 s:= s; // avoid compiler hint
-if not isExternalSource then
+if (not isExternalSource) then
     SendIPC(_S',');
 uStats.Skipped;
 skipFlag:= true
@@ -1289,7 +1283,7 @@
             // if team matches current hedgehog team, default to current hedgehog
             if (i = 0) and (CurrentHedgehog <> nil) and (CurrentHedgehog^.Team = TeamsArray[t]) then
                 hh:= CurrentHedgehog
-            else 
+            else
                 begin
             // otherwise use the first living hog or the hog amongs the remaining ones indicated by i
                 j:= 0;
@@ -1305,7 +1299,7 @@
                     inc(j)
                     end
                 end;
-        if hh <> nil then 
+        if hh <> nil then
             begin
             Gear:= AddVisualGear(0, 0, vgtSpeechBubble);
             if Gear <> nil then
--- a/hedgewars/uGearsHedgehog.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uGearsHedgehog.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -447,15 +447,15 @@
                 begin
                 elastic:=  int2hwfloat(CurWeapon^.Bounciness) / _1000;
 
-                if elastic < _1 then
-                    newGear^.Elasticity:= newGear^.Elasticity * elastic
-                else if elastic > _1 then
-                    newGear^.Elasticity:= _1 - ((_1-newGear^.Elasticity) / elastic);
-    (* Experimented with friction modifier. Didn't seem helpful
-                fric:= int2hwfloat(CurWeapon^.Bounciness) / _250;
-                if fric < _1 then newGear^.Friction:= newGear^.Friction * fric
-                else if fric > _1 then newGear^.Friction:= _1 - ((_1-newGear^.Friction) / fric)*)
-                end;
+            if elastic < _1 then
+                newGear^.Elasticity:= newGear^.Elasticity * elastic
+            else if elastic > _1 then
+                newGear^.Elasticity:= _1 - ((_1-newGear^.Elasticity) / elastic);
+(* Experimented with friction modifier. Didn't seem helpful
+            fric:= int2hwfloat(CurWeapon^.Bounciness) / _250;
+            if fric < _1 then newGear^.Friction:= newGear^.Friction * fric
+            else if fric > _1 then newGear^.Friction:= _1 - ((_1-newGear^.Friction) / fric)*)
+            end;
 
 
             uStats.AmmoUsed(CurAmmoType);
@@ -473,16 +473,15 @@
                 end;
 
             Power:= 0;
-            if (CurAmmoGear <> nil)
-                and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) = 0){check for dropping ammo from rope} then
+            if (CurAmmoGear <> nil) and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) = 0){check for dropping ammo from rope} then
                 begin
-                if CurAmmoType in [amRope,amResurrector] then Message:= Message or gmAttack;
+                if CurAmmoType in [amRope,amResurrector] then
+                    Message:= Message or gmAttack;
                 CurAmmoGear^.Message:= Message
                 end
             else
                 begin
-                if not CurrentTeam^.ExtDriven
-                and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0) then
+                if (not CurrentTeam^.ExtDriven) and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0) then
                     SendIPC(_S'a');
                 AfterAttack;
                 end
@@ -1039,6 +1038,11 @@
 else if Hedgehog^.CurAmmoType in [amShotgun, amDEagle, amSniperRifle] then
     HHGear^.Message:= 0;
 
+if ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_Utility) <> 0) and isInMultiShoot then
+    AllInactive:= true
+else if not isInMultiShoot then
+    AllInactive:= false;
+
 if (TurnTimeLeft = 0) or (HHGear^.Damage > 0) then
     begin
     if (Hedgehog^.CurAmmoType = amKnife) then
--- a/hedgewars/uGearsList.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uGearsList.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -158,8 +158,10 @@
 var gear: PGear;
 begin
 inc(GCounter);
+
 AddFileLog('AddGear: #' + inttostr(GCounter) + ' (' + inttostr(x) + ',' + inttostr(y) + '), d(' + floattostr(dX) + ',' + floattostr(dY) + ') type = ' + EnumToStr(Kind));
 
+
 New(gear);
 FillChar(gear^, sizeof(TGear), 0);
 gear^.X:= int2hwFloat(X);
@@ -606,7 +608,7 @@
             begin
             t:= max(Gear^.Damage, Gear^.Health);
             Gear^.Damage:= t;
-            if ((not SuddenDeathDmg and (WaterOpacity < $FF)) or (SuddenDeathDmg and (WaterOpacity < $FF)))
+            if (((not SuddenDeathDmg) and (WaterOpacity < $FF)) or (SuddenDeathDmg and (WaterOpacity < $FF)))
             and (hwRound(Gear^.Y) < cWaterLine + 256) then
                 spawnHealthTagForHH(Gear, t);
             end;
--- a/hedgewars/uGearsRender.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uGearsRender.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -23,6 +23,18 @@
 interface
 uses uTypes, uConsts, GLunit, uFloat, SDLh;
 
+type
+   Tar         = record
+            X, Y: hwFloat;
+            dLen: hwFloat;
+            b : boolean;
+         end;
+   TRopePoints = record
+            Count     : Longword;
+            HookAngle : GLfloat;
+            ar        : array[0..MAXROPEPOINTS] of Tar;
+            rounded   : array[0..MAXROPEPOINTS + 2] of TVertex2f;
+         end;
 procedure RenderGear(Gear: PGear; x, y: LongInt);
 
 var RopePoints: record
@@ -91,6 +103,7 @@
     if (X1 = X2) and (Y1 = Y2) then
         begin
         //OutError('WARNING: zero length rope line!', false);
+    DrawRopeLine := 0;
         exit
         end;
     eX:= 0;
@@ -1232,7 +1245,7 @@
                         begin
                         if isInLag and (Gear^.FlightTime < 256) then
                             inc(Gear^.FlightTime, 8)
-                        else if not isInLag and (Gear^.FlightTime > 0) then
+                        else if (not isInLag) and (Gear^.FlightTime > 0) then
                             dec(Gear^.FlightTime, 8);
                         if Gear^.FlightTime > 0 then
                             Tint($FF, $FF, $FF, $FF-min(255,Gear^.FlightTime));
--- a/hedgewars/uGearsUtils.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uGearsUtils.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -23,7 +23,7 @@
 uses uTypes;
 
 procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword); inline;
-procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord); 
+procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord);
 
 function  ModifyDamage(dmg: Longword; Gear: PGear): Longword;
 procedure ApplyDamage(Gear: PGear; AttackerHog: PHedgehog; Damage: Longword; Source: TDamageSource);
@@ -233,7 +233,7 @@
                         end;
                     end
                 end;
-        if ((GameFlags and gfKarma) <> 0) and 
+        if ((GameFlags and gfKarma) <> 0) and
         ((GameFlags and gfInvulnerable) = 0)
         and (not CurrentHedgehog^.Gear^.Invulnerable) then
             begin // this cannot just use Damage or it interrupts shotgun and gets you called stupid
@@ -241,13 +241,13 @@
             CurrentHedgehog^.Gear^.LastDamage := CurrentHedgehog;
             spawnHealthTagForHH(CurrentHedgehog^.Gear, tmpDmg);
             end;
-        uStats.HedgehogDamaged(Gear, AttackerHog, Damage, false);    
+        uStats.HedgehogDamaged(Gear, AttackerHog, Damage, false);
         end;
     end else
     //else if Gear^.Kind <> gtStructure then // not gtHedgehog nor gtStructure
         Gear^.Hedgehog:= AttackerHog;
     inc(Gear^.Damage, Damage);
-    
+
     ScriptCall('onGearDamage', Gear^.UID, Damage);
 end;
 
@@ -260,7 +260,7 @@
 AllInactive:= false;
 HHGear^.Active:= true;
 end;
-    
+
 procedure HHHurt(Hedgehog: PHedgehog; Source: TDamageSource);
 begin
 if Hedgehog^.Effects[heFrozen] <> 0 then exit;
@@ -285,7 +285,7 @@
 end;
 
 procedure CheckHHDamage(Gear: PGear);
-var 
+var
     dmg: Longword;
     i: LongWord;
     particle: PVisualGear;
@@ -323,7 +323,7 @@
 
 
 procedure CalcRotationDirAngle(Gear: PGear);
-var 
+var
     dAngle: real;
 begin
     // Frac/Round to be kind to JS as of 2012-08-27 where there is yet no int64/uint64
@@ -418,7 +418,7 @@
             and (CurAmmoGear^.dY < _0_01))) then
                 if Gear^.Density * Gear^.dY > _1 then
                     PlaySound(sndSplash)
-                else if Gear^.Density * Gear^.dY > _0_5 then 
+                else if Gear^.Density * Gear^.dY > _0_5 then
                     PlaySound(sndSkip)
                 else
                     PlaySound(sndDroplet2);
@@ -430,7 +430,7 @@
         and (CurAmmoGear^.dY < _0_01)))) then
             begin
             splash:= AddVisualGear(X, cWaterLine, vgtSplash);
-            if splash <> nil then 
+            if splash <> nil then
                 with splash^ do
                 begin
                 Scale:= hwFloat2Float(Gear^.Density / _3 * Gear^.dY);
@@ -453,12 +453,12 @@
                         dY := dY - vdY / 5;
                         if splash <> nil then
                             begin
-                            if splash^.Scale > 1 then 
+                            if splash^.Scale > 1 then
                                 begin
                                 dX:= dX * power(splash^.Scale,0.3333); // tone down the droplet height further
                                 dY:= dY * power(splash^.Scale, 0.3333)
                                 end
-                            else 
+                            else
                                 begin
                                 dX:= dX * splash^.Scale;
                                 dY:= dY * splash^.Scale
@@ -492,7 +492,7 @@
     gear^.Hedgehog^.Effects[hePoisoned] := 0;
     if (CurrentHedgehog^.Effects[heResurrectable] = 0) or ((CurrentHedgehog^.Effects[heResurrectable] <> 0)
           and (Gear^.Hedgehog^.Team^.Clan <> CurrentHedgehog^.Team^.Clan)) then
-        with CurrentHedgehog^ do 
+        with CurrentHedgehog^ do
             begin
             inc(Team^.stats.AIKills);
             FreeTexture(Team^.AIKillsTex);
@@ -509,7 +509,7 @@
         sparkles^.Tint:= tempTeam^.Clan^.Color shl 8 or $FF;
         //sparkles^.Angle:= random(360);
         end;
-    FindPlace(gear, false, 0, LAND_WIDTH, true); 
+    FindPlace(gear, false, 0, LAND_WIDTH, true);
     if gear <> nil then
         begin
         AddVisualGear(hwRound(gear^.X), hwRound(gear^.Y), vgtExplosion);
@@ -567,6 +567,7 @@
     y, sy: LongInt;
     ar: array[0..1023] of TPoint;
     ar2: array[0..2047] of TPoint;
+    temp: TPoint;
     cnt, cnt2: Longword;
     delta: LongInt;
     ignoreNearObjects, ignoreOverlap, tryAgain: boolean;
@@ -589,7 +590,7 @@
                 repeat
                     inc(y, 2);
                 until (y >= cWaterLine) or
-                        (not ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, $FFFF) = 0)) or 
+                        ((not ignoreOverlap) and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, $FFFF) = 0)) or 
                         (ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, lfLandMask) = 0));
 
                 sy:= y;
@@ -597,7 +598,7 @@
                 repeat
                     inc(y);
                 until (y >= cWaterLine) or
-                        (not ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, $FFFF) <> 0)) or 
+                        ((not ignoreOverlap) and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, $FFFF) <> 0)) or 
                         (ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, lfLandMask) <> 0)); 
 
                 if (y - sy > Gear^.Radius * 2)
@@ -623,12 +624,15 @@
                 end;
 
             if cnt > 0 then
-                with ar[GetRandom(cnt)] do
+        begin
+           temp := ar[GetRandom(cnt)];
+               with temp do
                     begin
                     ar2[cnt2].x:= x;
                     ar2[cnt2].y:= y;
                     inc(cnt2)
-                    end
+            end
+           end
         until (x + Delta > Right);
 
         dec(Delta, 60)
@@ -642,12 +646,15 @@
     end;
 
 if cnt2 > 0 then
-    with ar2[GetRandom(cnt2)] do
+    begin
+    temp := ar2[GetRandom(cnt2)];
+    with temp do
         begin
         Gear^.X:= int2hwFloat(x);
         Gear^.Y:= int2hwFloat(y);
         AddFileLog('Assigned Gear coordinates (' + inttostr(x) + ',' + inttostr(y) + ')');
         end
+    end
     else
     begin
     OutError('Can''t find place for Gear', false);
@@ -693,7 +700,7 @@
     if TestCollisionX(Gear, hwSign(Gear^.dX))
     or TestCollisionY(Gear, hwSign(Gear^.dY)) then
         Gear^.State := Gear^.State or gstCollision
-    else 
+    else
         Gear^.State := Gear^.State and (not gstCollision)
 end;
 
--- a/hedgewars/uIO.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uIO.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -20,7 +20,7 @@
 
 unit uIO;
 interface
-uses SDLh, uTypes;
+uses SDLh, uTypes, uMisc;
 
 procedure initModule;
 procedure freeModule;
@@ -122,6 +122,7 @@
 procedure ParseIPCCommand(s: shortstring);
 var loTicks: Word;
 begin
+
 case s[1] of
      '!': begin AddFileLog('Ping? Pong!'); isPonged:= true; end;
      '?': SendIPC(_S'!');
@@ -177,10 +178,11 @@
 end;
 
 procedure LoadRecordFromFile(fileName: shortstring);
-var f: file;
-    ss: shortstring = '';
-    i: LongInt;
-    s: shortstring;
+var f  : File;
+    ss : shortstring = '';
+    i  : LongInt;
+    s  : shortstring;
+   t, tt   : string;
 begin
 
 // set RDNLY on file open
@@ -188,7 +190,6 @@
 {$I-}
 assign(f, fileName);
 reset(f, 1);
-
 tryDo(IOResult = 0, 'Error opening file ' + fileName, true);
 
 i:= 0; // avoid compiler hints
@@ -196,13 +197,13 @@
 repeat
     BlockRead(f, s[1], 255 - Length(ss), i);
     if i > 0 then
-        begin
+    begin
         s[0]:= char(i);
         ss:= ss + s;
         while (Length(ss) > 1)and(Length(ss) > byte(ss[1])) do
             begin
             ParseIPCCommand(copy(ss, 2, byte(ss[1])));
-            Delete(ss, 1, Succ(byte(ss[1])))
+           Delete(ss, 1, Succ(byte(ss[1])));
             end
         end
 until i = 0;
@@ -221,7 +222,11 @@
 
 function isSyncedCommand(c: char): boolean;
 begin
-    isSyncedCommand:= (c in ['+', '#', 'L', 'l', 'R', 'r', 'U', 'u', 'D', 'd', 'Z', 'z', 'A', 'a', 'S', 'j', 'J', ',', 'c', 'N', 'p', 'P', 'w', 't', '1', '2', '3', '4', '5']) or ((c >= #128) and (c <= char(128 + cMaxSlotIndex)))
+    case c of
+        '+', '#', 'L', 'l', 'R', 'r', 'U', 'u', 'D', 'd', 'Z', 'z', 'A', 'a', 'S', 'j', 'J', ',', 'c', 'N', 'p', 'P', 'w', 't', '1', '2', '3', '4', '5': isSyncedCommand:= true;
+    else
+        isSyncedCommand:= ((c >= #128) and (c <= char(128 + cMaxSlotIndex)))
+    end
 end;
 
 procedure flushBuffer();
@@ -240,7 +245,7 @@
     begin
     if s[0] > #251 then
         s[0]:= #251;
-        
+
     SDLNet_Write16(GameTicks, @s[Succ(byte(s[0]))]);
     
     AddFileLog('[IPC out] '+ sanitizeCharForLog(s[1]));
@@ -418,7 +423,7 @@
 if CheckNoTeamOrHH or isPaused then
     exit;
 bShowFinger:= false;
-if not CurrentTeam^.ExtDriven and bShowAmmoMenu then
+if (not CurrentTeam^.ExtDriven) and bShowAmmoMenu then
     begin
     bSelected:= true;
     exit
@@ -468,7 +473,7 @@
     lastcmd:= nil;
     isPonged:= false;
     SocketString:= '';
-    
+
     hiTicks:= 0;
     flushDelayTicks:= 0;
     sendBuffer.count:= 0;
@@ -480,6 +485,7 @@
     SDLNet_FreeSocketSet(fds);
     SDLNet_TCP_Close(IPCSock);
     SDLNet_Quit();
+
 end;
 
 end.
--- a/hedgewars/uInputHandler.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uInputHandler.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -55,7 +55,7 @@
     LALT   = $0800;
     RALT   = $1000;
     LCTRL  = $2000;
-    RCTRL  = $4000; 
+    RCTRL  = $4000;
 
 var tkbd: array[0..cKbdMaxIndex] of boolean;
     KeyNames: array [0..cKeyMaxIndex] of string[15];
@@ -90,12 +90,12 @@
 (*
 procedure MaskModifier(var code: LongInt; Modifier: LongWord);
 begin
-    if(Modifier and KMOD_LSHIFT) <> 0 then code:= code or LSHIFT; 
-    if(Modifier and KMOD_RSHIFT) <> 0 then code:= code or LSHIFT; 
-    if(Modifier and KMOD_LALT) <> 0 then code:= code or LALT; 
-    if(Modifier and KMOD_RALT) <> 0 then code:= code or LALT; 
-    if(Modifier and KMOD_LCTRL) <> 0 then code:= code or LCTRL; 
-    if(Modifier and KMOD_RCTRL) <> 0 then code:= code or LCTRL; 
+    if(Modifier and KMOD_LSHIFT) <> 0 then code:= code or LSHIFT;
+    if(Modifier and KMOD_RSHIFT) <> 0 then code:= code or LSHIFT;
+    if(Modifier and KMOD_LALT) <> 0 then code:= code or LALT;
+    if(Modifier and KMOD_RALT) <> 0 then code:= code or LALT;
+    if(Modifier and KMOD_LCTRL) <> 0 then code:= code or LCTRL;
+    if(Modifier and KMOD_RCTRL) <> 0 then code:= code or LCTRL;
 end;
 *)
 procedure MaskModifier(Modifier: shortstring; var code: LongInt);
@@ -111,7 +111,7 @@
 SplitByChar(Modifier, mod_, ':');//remove the first mod: part
 Modifier:= mod_;
 for i:= 0 to ModifierCount do
-    begin 
+    begin
     mod_:= '';
     SplitByChar(Modifier, mod_, ':');
     if (Modifier = 'lshift')                    then code:= code or LSHIFT;
@@ -232,7 +232,7 @@
     s:= shortstring(sdl_getkeyname(i));
     //WriteLnToConsole('uInputHandler - ' + IntToStr(i) + ': ' + s + ' ' + IntToStr(cKeyMaxIndex));
     if s = 'unknown key' then KeyNames[i]:= ''
-    else 
+    else
         begin
         for t:= 1 to Length(s) do
             if s[t] = ' ' then
@@ -390,10 +390,10 @@
             if ControllerNumAxes[j] > 20 then
                 ControllerNumAxes[j]:= 20;
             //if ControllerNumBalls[j] > 20 then ControllerNumBalls[j]:= 20;
-            
+
             if ControllerNumHats[j] > 20 then
                 ControllerNumHats[j]:= 20;
-                
+
             if ControllerNumButtons[j] > 20 then
                 ControllerNumButtons[j]:= 20;
 
@@ -461,7 +461,7 @@
 if (not usingDBinds) then
     begin
     usingDBinds:= true;
-    FillByte(DefaultBinds, SizeOf(DefaultBinds), 0);
+    FillChar(DefaultBinds, SizeOf(DefaultBinds), 0);
     end;
 
 if (Pos('mod:', id) <> 0) then
--- a/hedgewars/uLand.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uLand.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -37,7 +37,7 @@
 
 procedure ResizeLand(width, height: LongWord);
 var potW, potH: LongInt;
-begin 
+begin
 potW:= toPowerOf2(width);
 potH:= toPowerOf2(height);
 if (potW <> LAND_WIDTH) or (potH <> LAND_HEIGHT) then
@@ -240,6 +240,7 @@
     rightX:= (playWidth + ((LAND_WIDTH - playWidth) div 2)) - 1;
     topY:= LAND_HEIGHT - playHeight;
 
+
     // HACK: force to only cavern even if a cavern map is invertable if cTemplateFilter = 4 ?
     if (cTemplateFilter = 4)
     or (Template.canInvert and (getrandom(2) = 0))
@@ -339,7 +340,7 @@
     SDL_FreeSurface(tmpsurf);
     for x:= leftX+2 to rightX-2 do
         for y:= topY+2 to LAND_HEIGHT-3 do
-            if (Land[y, x] = 0) and 
+            if (Land[y, x] = 0) and
                (((Land[y, x-1] = lfBasic) and ((Land[y+1,x] = lfBasic)) or (Land[y-1,x] = lfBasic)) or
                ((Land[y, x+1] = lfBasic) and ((Land[y-1,x] = lfBasic) or (Land[y+1,x] = lfBasic)))) then
             begin
@@ -347,16 +348,16 @@
                     begin
                     if (Land[y, x-1] = lfBasic) and (LandPixels[y, x-1] and AMask <> 0) then
                         LandPixels[y, x]:= LandPixels[y, x-1]
-                        
+
                     else if (Land[y, x+1] = lfBasic) and (LandPixels[y, x+1] and AMask <> 0) then
                         LandPixels[y, x]:= LandPixels[y, x+1]
-                        
+
                     else if (Land[y-1, x] = lfBasic) and (LandPixels[y-1, x] and AMask <> 0) then
                         LandPixels[y, x]:= LandPixels[y-1, x]
-                        
+
                     else if (Land[y+1, x] = lfBasic) and (LandPixels[y+1, x] and AMask <> 0) then
                         LandPixels[y, x]:= LandPixels[y+1, x];
-                        
+
                     if (((LandPixels[y,x] and AMask) shr AShift) > 10) then
                         LandPixels[y,x]:= (LandPixels[y,x] and (not AMask)) or (128 shl AShift)
                     end;
@@ -371,25 +372,25 @@
                     ((Land[y-1, x] = lfBasic) and (Land[y-1,x+1] = lfBasic) and (Land[y,x+2] = lfBasic)) or
                     ((Land[y+1, x] = lfBasic) and (Land[y+1,x-1] = lfBasic) and (Land[y,x-2] = lfBasic)) or
                     ((Land[y-1, x] = lfBasic) and (Land[y-1,x-1] = lfBasic) and (Land[y,x-2] = lfBasic))) then
-                    
+
                 begin
-                
+
                 if (cReducedQuality and rqBlurryLand) = 0 then
-                
+
                     begin
-                    
+
                     if (Land[y, x-1] = lfBasic) and (LandPixels[y,x-1] and AMask <> 0) then
                         LandPixels[y, x]:= LandPixels[y, x-1]
-                        
+
                     else if (Land[y, x+1] = lfBasic) and (LandPixels[y,x+1] and AMask <> 0) then
                         LandPixels[y, x]:= LandPixels[y, x+1]
-                        
+
                     else if (Land[y+1, x] = lfBasic) and (LandPixels[y+1,x] and AMask <> 0) then
                         LandPixels[y, x]:= LandPixels[y+1, x]
-                        
+
                     else if (Land[y-1, x] = lfBasic) and (LandPixels[y-1,x] and AMask <> 0) then
                         LandPixels[y, x]:= LandPixels[y-1, x];
-                        
+
                     if (((LandPixels[y,x] and AMask) shr AShift) > 10) then
                         LandPixels[y,x]:= (LandPixels[y,x] and (not AMask)) or (64 shl AShift)
                     end;
@@ -535,9 +536,11 @@
     LAND_HEIGHT - tmpsurf^.h,
     tmpsurf^.w,
     tmpsurf);
+
 SDL_FreeSurface(tmpsurf);
 
 LoadMask;
+
 end;
 
 procedure DrawBottomBorder; // broken out from other borders for doing a floor-only map, or possibly updating bottom during SD
@@ -602,7 +605,6 @@
         MakeFortsMap;
 
     AddProgress;
-
 // check for land near top
 c:= 0;
 if (GameFlags and gfBorder) <> 0 then
@@ -675,7 +677,7 @@
 
 if (GameFlags and gfForts = 0) and (maskOnly or (cPathz[ptMapCurrent] = '')) then
     AddObjects
-    
+
 else
     AddProgress();
 
@@ -731,7 +733,7 @@
         rw:= rh*2;
         end;
     if rh < rw div 2 then rh:= rw * 2;
-    
+
     ox:= (rw-LAND_WIDTH) div 2;
     oy:= rh-LAND_HEIGHT;
 
@@ -747,7 +749,7 @@
                 cbit:= bit * 8;
                 for yy:= y * lh to y * lh + 7 do
                     for xx:= x * lw + cbit to x * lw + cbit + 7 do
-                        if ((yy-oy) and LAND_HEIGHT_MASK = 0) and ((xx-ox) and LAND_WIDTH_MASK = 0) 
+                        if ((yy-oy) and LAND_HEIGHT_MASK = 0) and ((xx-ox) and LAND_WIDTH_MASK = 0)
                            and (Land[yy-oy, xx-ox] <> 0) then
                             inc(t);
                 if t > 8 then
@@ -770,8 +772,10 @@
 var adler, i: LongInt;
 begin
     adler:= 1;
-    for i:= 0 to LAND_HEIGHT-1 do
+     for i:= 0 to LAND_HEIGHT-1 do
+       begin
         adler:= Adler32Update(adler, @Land[i,0], LAND_WIDTH);
+       end;
     s:= 'M' + IntToStr(adler) + cScriptName;
 
     chLandCheck(s);
--- a/hedgewars/uLandGenMaze.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uLandGenMaze.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -16,6 +16,10 @@
     DIR_S: direction = (x: 0; y: 1);
     DIR_W: direction = (x: -1; y: 0);
 
+{xymeng : make all dynamic arrays static }
+const max_num_cells_x = 4096 div 128;
+   max_num_cells_y    = 4096 div 128;
+   max_num_steps      = 3;
 
 operator = (const a, b: direction) c: Boolean;
 begin
@@ -27,28 +31,43 @@
     large_cell_size = 256;
     braidness = 10;
 
-var x, y: LongInt;
-    cellsize: LongInt; //selected by the user in the gui
-    seen_cells_x, seen_cells_y: LongInt; //number of cells that can be visited by the generator, that is every second cell in x and y direction. the cells between there are walls that will be removed when we move from one cell to another
-    num_edges_x, num_edges_y: LongInt; //number of resulting edges that need to be vertexificated
-    num_cells_x, num_cells_y: LongInt; //actual number of cells, depending on cell size
-    seen_list: array of array of LongInt;
-    xwalls: array of array of Boolean;
-    ywalls: array of array of Boolean;
-    x_edge_list: array of array of Boolean;
-    y_edge_list: array of array of Boolean;
-    maze: array of array of Boolean;
-    pa: TPixAr;
-    num_vertices: LongInt;
-    off_y: LongInt;
-    num_steps: LongInt;
-    current_step: LongInt;
-    step_done: array of Boolean;
-    done: Boolean;
-    last_cell: array of record x, y: LongInt; end;
-    came_from: array of array of record x, y: LongInt; end;
+type
+   cell_t = record x,y	       : LongInt
+	    end;
+   
+var x, y		       : LongInt;
+    cellsize		       : LongInt; //selected by the user in the gui
+    seen_cells_x, seen_cells_y : LongInt; //number of cells that can be visited by the generator, that is every second cell in x and y direction. the cells between there are walls that will be removed when we move from one cell to another
+    num_edges_x, num_edges_y   : LongInt; //number of resulting edges that need to be vertexificated
+    num_cells_x, num_cells_y   : LongInt; //actual number of cells, depending on cell size
+
+
+    seen_list		       : array of array of LongInt;
+    xwalls		       : array of array of Boolean;
+    ywalls		       : array of array of Boolean;
+    x_edge_list		       : array of array of Boolean;
+    y_edge_list		       : array of array of Boolean;
+    maze		       : array of array of Boolean;
+
+    pa			       : TPixAr;
+    num_vertices	       : LongInt;
+    off_y		       : LongInt;
+    num_steps		       : LongInt;
+    current_step	       : LongInt;
+   
+    step_done		       : array of Boolean;
+   
+    done		       : Boolean;
+
+{   last_cell		       : array 0..3 of record x, y :LongInt ; end;
+    came_from		       : array of array of record x, y: LongInt; end;
+    came_from_pos	       : array of LongInt;
+}
+    last_cell : array of cell_t;
+    came_from : array of array of cell_t;
     came_from_pos: array of LongInt;
-    maze_inverted: Boolean;
+   
+    maze_inverted					   : Boolean;
 
 function when_seen(x: LongInt; y: LongInt): LongInt;
 begin
@@ -104,7 +123,7 @@
     begin
         //we have already seen the target cell, decide if we should remove the wall anyway
         //(or put a wall there if maze_inverted, but we are not doing that right now)
-        if not maze_inverted and (GetRandom(braidness) = 0) then
+        if (not maze_inverted) and (GetRandom(braidness) = 0) then
         //or just warn that inverted+braid+indestructible terrain != good idea
         begin
             case dir.x of
@@ -180,7 +199,7 @@
     came_from_pos[current_step] := came_from_pos[current_step] - 1;
     
     if came_from_pos[current_step] >= 0 then
-        see_cell
+        see_cell()
         
     else
         step_done[current_step] := true;
@@ -338,14 +357,18 @@
 SetLength(last_cell, num_steps);
 SetLength(came_from_pos, num_steps);
 SetLength(came_from, num_steps, num_cells_x*num_cells_y);
+
 done := false;
 
 for current_step := 0 to num_steps - 1 do
+begin
     step_done[current_step] := false;
     came_from_pos[current_step] := 0;
-    
+end;
+
 current_step := 0;
 
+
 SetLength(seen_list, seen_cells_x, seen_cells_y);
 SetLength(xwalls, seen_cells_x, seen_cells_y - 1);
 SetLength(ywalls, seen_cells_x - 1, seen_cells_y);
@@ -353,6 +376,7 @@
 SetLength(y_edge_list, num_cells_x, num_edges_y);
 SetLength(maze, num_cells_x, num_cells_y);
 
+   
 num_vertices := 0;
 
 playHeight := num_cells_y * cellsize;
--- a/hedgewars/uLandGraphics.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uLandGraphics.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -87,21 +87,21 @@
 if ((Land[landY, landX] and lfBasic) <> 0) or ((Land[landY, landX] and lfObject) <> 0) then
     begin
     LandPixels[pixelY, pixelX]:= ExplosionBorderColor;
-    Land[landY, landX]:= (Land[landY, landX] or lfDamaged) and not lfIce;
+    Land[landY, landX]:= (Land[landY, landX] or lfDamaged) and (not lfIce);
     LandDirty[landY div 32, landX div 32]:= 1;
     end;
 end;
 
 function isLandscapeEdge(weight:Longint):boolean; inline;
 begin
-result := (weight < 8) and (weight >= 2);
+isLandscapeEdge := (weight < 8) and (weight >= 2);
 end;
 
 function getPixelWeight(x, y:Longint): Longint;
 var
-    i, j:Longint;
+    i, j, r: Longint;
 begin
-result := 0;
+r := 0;
 for i := x - 1 to x + 1 do
     for j := y - 1 to y + 1 do
     begin
@@ -109,13 +109,13 @@
        (i > LAND_WIDTH - 1) or
        (j < 0) or
        (j > LAND_HEIGHT -1) then
-       begin
-       result := 9;
-       exit;
-       end;
-    if Land[j, i] and lfLandMask and not lfIce = 0 then
-       result := result + 1;
+       exit(9);
+
+    if Land[j, i] and lfLandMask and (not lfIce) = 0 then
+       inc(r)
     end;
+
+    getPixelWeight:= r
 end;
 
 
@@ -142,11 +142,11 @@
         end
     else
         begin
-        LandPixels[pixelY, pixelX]:= IceColor and not AMask or $E8 shl AShift;
+        LandPixels[pixelY, pixelX]:= IceColor and (not AMask) or $E8 shl AShift;
         LandPixels[pixelY, pixelX]:= addBgColor(LandPixels[pixelY, pixelX], icePixels^[iceSurface^.w * (pixelY mod iceSurface^.h) + (pixelX mod iceSurface^.w)]);
         // silly workaround to avoid having to make background erasure a tadb it smarter about sea ice
         if LandPixels[pixelY, pixelX] and AMask shr AShift = 255 then
-            LandPixels[pixelY, pixelX]:= LandPixels[pixelY, pixelX] and not AMask or 254 shl AShift;
+            LandPixels[pixelY, pixelX]:= LandPixels[pixelY, pixelX] and (not AMask) or 254 shl AShift;
         end;
 end;
 
@@ -157,7 +157,7 @@
 if isLandscapeEdge(getPixelWeight(landX, landY)) then
     begin
     if (LandPixels[pixelY, pixelX] and AMask < 255) and (LandPixels[pixelY, pixelX] and AMask > 0) then
-        LandPixels[pixelY, pixelX] := (IceEdgeColor and not AMask) or (LandPixels[pixelY, pixelX] and AMask)
+        LandPixels[pixelY, pixelX] := (IceEdgeColor and (not AMask)) or (LandPixels[pixelY, pixelX] and AMask)
     else if (LandPixels[pixelY, pixelX] and AMask < 255) or (Land[landY, landX] > 255) then
         LandPixels[pixelY, pixelX] := IceEdgeColor
     end
@@ -165,7 +165,7 @@
     begin
         fillPixelFromIceSprite(pixelX, pixelY);
     end;
-if Land[landY, landX] > 255 then Land[landY, landX] := Land[landY, landX] or lfIce and not lfDamaged;
+if Land[landY, landX] > 255 then Land[landY, landX] := Land[landY, landX] or lfIce and (not lfDamaged);
 end;
 
 
@@ -342,11 +342,11 @@
 begin
 if not doSet and isCurrent then
     FillRoundInLand(X, Y, Radius, setNotCurrentMask)
-else if not doSet and not IsCurrent then
+else if not doSet and (not IsCurrent) then
     FillRoundInLand(X, Y, Radius, changePixelSetNotCurrent)
 else if doSet and IsCurrent then
     FillRoundInLand(X, Y, Radius, setCurrentHog)
-else if doSet and not IsCurrent then
+else if doSet and (not IsCurrent) then
     FillRoundInLand(X, Y, Radius, changePixelNotSetNotCurrent);
 end;
 
@@ -430,7 +430,7 @@
                 else
                     LandPixels[ty div 2, tx div 2]:= ExplosionBorderColor;
 
-                Land[ty, tx]:= (Land[ty, tx] or lfDamaged) and not lfIce;
+                Land[ty, tx]:= (Land[ty, tx] or lfDamaged) and (not lfIce);
                 LandDirty[ty div 32, tx div 32]:= 1;
                 end;
     inc(y, dY)
@@ -455,7 +455,7 @@
     if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) and (((Land[ty, tx] and lfBasic) <> 0)
     or ((Land[ty, tx] and lfObject) <> 0)) then
         begin
-        Land[ty, tx]:= (Land[ty, tx] or lfDamaged) and not lfIce;
+        Land[ty, tx]:= (Land[ty, tx] or lfDamaged) and (not lfIce);
         if despeckle then
             LandDirty[ty div 32, tx div 32]:= 1;
         if (cReducedQuality and rqBlurryLand) = 0 then
@@ -499,7 +499,7 @@
     and ((tx and LAND_WIDTH_MASK) = 0)
     and (((Land[ty, tx] and lfBasic) <> 0) or ((Land[ty, tx] and lfObject) <> 0)) then
         begin
-        Land[ty, tx]:= Land[ty, tx] and not lfIce;
+        Land[ty, tx]:= Land[ty, tx] and (not lfIce);
         if despeckle then
             begin
             Land[ty, tx]:= Land[ty, tx] or lfDamaged;
@@ -563,7 +563,7 @@
     if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) and (((Land[ty, tx] and lfBasic) <> 0)
     or ((Land[ty, tx] and lfObject) <> 0)) then
         begin
-        Land[ty, tx]:= (Land[ty, tx] or lfDamaged) and not lfIce;
+        Land[ty, tx]:= (Land[ty, tx] or lfDamaged) and (not lfIce);
         if despeckle then
             LandDirty[ty div 32, tx div 32]:= 1;
         if (cReducedQuality and rqBlurryLand) = 0 then
--- a/hedgewars/uLandObjects.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uLandObjects.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -94,7 +94,7 @@
 begin
     BlitImageAndGenerateCollisionInfo(cpX, cpY, Width, Image, 0);
 end;
-    
+
 procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface; extraFlags: Word);
 var p: PLongwordArray;
     x, y: Longword;
@@ -124,7 +124,7 @@
                     LandPixels[cpY + y, cpX + x]:= p^[x];
                 end
             else
-                if LandPixels[(cpY + y) div 2, (cpX + x) div 2] = 0 then 
+                if LandPixels[(cpY + y) div 2, (cpX + x) div 2] = 0 then
                     LandPixels[(cpY + y) div 2, (cpX + x) div 2]:= p^[x];
 
             if (Land[cpY + y, cpX + x] <= lfAllObjMask) and ((p^[x] and AMask) <> 0) then
@@ -264,7 +264,7 @@
         inc(x2, 2);
         k:= CountNonZeroz(x2, y)
         until (x2 >= (rightX-150)) or (k = 0) or (k = 16) or (x2 > i) or (x2 - x1 >= 768);
-        
+
         if (x2 < (rightX - 150)) and (k = 16) and (x2 - x1 > 250) and (x2 - x1 < 768)
         and (not CheckIntersect(x1 - 32, y - 64, x2 - x1 + 64, 144)) then
                 break;
@@ -281,7 +281,7 @@
     while rr.x < x2 do
         begin
         // For testing only. Intent is to flag this on objects with masks, or use it for an ice ray gun
-        if (Theme = 'Snow') or (Theme = 'Christmas') then 
+        if (Theme = 'Snow') or (Theme = 'Christmas') then
             BlitImageAndGenerateCollisionInfo(rr.x, y, min(x2 - rr.x, tmpsurf^.w), tmpsurf, lfIce)
         else
             BlitImageAndGenerateCollisionInfo(rr.x, y, min(x2 - rr.x, tmpsurf^.w), tmpsurf);
@@ -458,9 +458,9 @@
 
 procedure CheckRect(Width, Height, x, y, w, h: LongWord);
 begin
-    if (x + w > Width) then 
+    if (x + w > Width) then
         OutError('Object''s rectangle exceeds image: x + w (' + inttostr(x) + ' + ' + inttostr(w) + ') > Width (' + inttostr(Width) + ')', true);
-    if (y + h > Height) then 
+    if (y + h > Height) then
         OutError('Object''s rectangle exceeds image: y + h (' + inttostr(y) + ' + ' + inttostr(h) + ') > Height (' + inttostr(Height) + ')', true);
 end;
 
@@ -558,7 +558,7 @@
             c2.g:= t;
             c2.b:= t
             end;
-        ExplosionBorderColor:= (c2.r shl RShift) or (c2.g shl GShift) or (c2.b shl BShift) or AMask; 
+        ExplosionBorderColor:= (c2.r shl RShift) or (c2.g shl GShift) or (c2.b shl BShift) or AMask;
         end
     else if key = 'water-top' then
         begin
--- a/hedgewars/uLandOutline.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uLandOutline.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -27,8 +27,6 @@
                                      end
            end;
 
-const
-    cMaxEdgePoints = 16384;
 
 procedure Push(_xl, _xr, _y, _dir: LongInt);
 begin
@@ -99,9 +97,9 @@
     i:= 0;
     with pa do
         while i < LongInt(Count) - 1 do
-            if (ar[i + 1].X = NTPX) then 
+            if (ar[i + 1].X = NTPX) then
                 inc(i, 2)
-            else 
+            else
                 begin
                 DrawLine(ar[i].x, ar[i].y, ar[i + 1].x, ar[i + 1].y, Color);
                 inc(i)
@@ -130,7 +128,7 @@
         begin
         Vx:= _0;
         Vy:= _0
-        end 
+        end
     else
         begin
         d2:= _1 / d2;
@@ -237,7 +235,7 @@
             CheckIntersect:= false
         else if (c2 < 0) or (c2 > dm) then
             CheckIntersect:= false;
-    end 
+    end
     else
     begin
         if (c1 > 0) or (c1 < dm) then
--- a/hedgewars/uLandTemplates.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uLandTemplates.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -24,20 +24,20 @@
 
 const NTPX = Low(SmallInt);
 
-type TPointArray = array[0..64] of TSDL_Rect;
-     PPointArray = ^TPointArray;
+type TPointArray   = array[0..64] of TSDL_Rect;
+     PPointArray   = ^TPointArray;
      TEdgeTemplate = record
-                     BasePoints: PPointArray;
-                     BasePointsCount: Longword;
-                     FillPoints: PPointArray;
-                     FillPointsCount: Longword;
-                     BezierizeCount: Longword;
-                     RandPassesCount: Longword;
-                     TemplateHeight, TemplateWidth: Longword;
-                     canMirror, canFlip, isNegative, canInvert: boolean;
-                     hasGirders: boolean;
-                     MaxHedgeHogs: Longword;
-                     end;
+			BasePoints				  : PPointArray;		  
+			BasePointsCount				  : Longword;
+			FillPoints				  : PPointArray;
+			FillPointsCount				  : Longword;
+			BezierizeCount				  : Longword;
+			RandPassesCount				  : Longword;
+			TemplateHeight, TemplateWidth		  : Longword;
+			canMirror, canFlip, isNegative, canInvert : boolean;
+			hasGirders				  : boolean;
+			MaxHedgeHogs				  : Longword;
+		     end;					  
 ///////////////////////// ORIGINAL SET //////////////////////////////
 /// Area expanded to 2848x1424 at Tiys request to move out border ///
 /////////////////////////////////////////////////////////////////////
@@ -63,9 +63,9 @@
        (x: 2134; y: 1424; w:    1; h:    1),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template0FPoints: array[0..0] of TPoint =
+      Template0FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 1023; Y:    0)
+       (X: 1023; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template1Points: array[0..15] of TSDL_Rect =
@@ -87,9 +87,9 @@
        (x: 1860; y: 1424; w:   25; h:    1),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template1FPoints: array[0..0] of TPoint =
+      Template1FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 1023; Y:    0)
+       (X: 1023; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template2Points: array[0..21] of TSDL_Rect =
@@ -117,9 +117,9 @@
        (x: 2004; y: 1424; w:    1; h:    1),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template2FPoints: array[0..0] of TPoint =
+      Template2FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 1023; Y:    0)
+       (X: 1023; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template3Points: array[0..16] of TSDL_Rect =
@@ -142,9 +142,9 @@
        (x: 1834; y:  622; w:  254; h:  116),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template3FPoints: array[0..0] of TPoint =
+      Template3FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 1023; Y:    0)
+       (X: 1023; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template4Points: array[0..22] of TSDL_Rect =
@@ -173,9 +173,9 @@
        (x: 2150; y:  552; w:   86; h:  220),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template4FPoints: array[0..0] of TPoint =
+      Template4FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 1023; Y:    0)
+       (X: 1023; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template5Points: array[0..15] of TSDL_Rect =
@@ -197,9 +197,9 @@
        (x: 2012; y: 1424; w:    1; h:    1),
        (x: NTPX; y:    0; w:    1; h:    1)
        );
-      Template5FPoints: array[0..0] of TPoint =
+      Template5FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 1023; Y:    0)
+       (X: 1023; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template6Points: array[0..13] of TSDL_Rect =
@@ -219,9 +219,9 @@
        (x: 2046; y: 1420; w:    2; h:    2),
        (x: NTPX; y:    0; w:    1; h:    1)
        );
-      Template6FPoints: array[0..0] of TPoint =
+      Template6FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 1023; Y:    0)
+       (X: 1023; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template7Points: array[0..5] of TSDL_Rect =
@@ -233,9 +233,9 @@
        (x: 1830; y: 1424; w:  454; h:    1),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template7FPoints: array[0..0] of TPoint =
+      Template7FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 1023; Y:    0)
+       (X: 1023; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 
@@ -262,9 +262,9 @@
        (x: 2030; y: 1424; w:   20; h:    1),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template8FPoints: array[0..0] of TPoint =
+      Template8FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 1023; Y:    0)
+       (X: 1023; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template9Points: array[0..31] of TSDL_Rect =
@@ -302,9 +302,9 @@
        (x: 2080; y: 1424; w:    1; h:    1),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template9FPoints: array[0..0] of TPoint =
+      Template9FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 1023; Y:    0)
+       (X: 1023; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template10Points: array[0..13] of TSDL_Rect =
@@ -324,9 +324,9 @@
        (x: 2182; y: 1424; w:    2; h:    1),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template10FPoints: array[0..0] of TPoint =
+      Template10FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 1023; Y:    0)
+       (X: 1023; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template11Points: array[0..9] of TSDL_Rect =
@@ -342,9 +342,9 @@
        (x: 1984; y: 1424; w:  136; h:    1),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template11FPoints: array[0..0] of TPoint =
+      Template11FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 1023; Y:    0)
+       (X: 1023; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template12Points: array[0..13] of TSDL_Rect =
@@ -364,9 +364,9 @@
        (x: 2088; y: 1424; w:  176; h:    1),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template12FPoints: array[0..0] of TPoint =
+      Template12FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 1023; Y:    0)
+       (X: 1023; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template13Points: array[0..15] of TSDL_Rect =
@@ -388,9 +388,9 @@
        (x: 1844; y: 1424; w:    2; h:    2),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template13FPoints: array[0..0] of TPoint =
+      Template13FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 1023; Y:    0)
+       (X: 1023; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template14Points: array[0..13] of TSDL_Rect =
@@ -410,9 +410,9 @@
        (x: 2008; y: 1424; w:    2; h:    2),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template14FPoints: array[0..0] of TPoint =
+      Template14FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 1023; Y:    0)
+       (X: 1023; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template15Points: array[0..23] of TSDL_Rect =
@@ -442,9 +442,9 @@
        (x: 2056; y: 1424; w:    2; h:    2),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template15FPoints: array[0..0] of TPoint =
+      Template15FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 1023; Y:    0)
+       (X: 1023; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template16Points: array[0..28] of TSDL_Rect =
@@ -479,9 +479,9 @@
        (x: 2098; y: 1424; w:   52; h:    2),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template16FPoints: array[0..0] of TPoint =
+      Template16FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 1023; Y:    0)
+       (X: 1023; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template17Points: array[0..13] of TSDL_Rect =
@@ -501,9 +501,9 @@
        (x: 1998; y: 1424; w:   42; h:    2),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template17FPoints: array[0..0] of TPoint =
+      Template17FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 1023; Y:    0)
+       (X: 1023; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 //////////////////// MIXING AND MATCHING ORIGINAL //////////////////////////////////////
 const Template18Points: array[0..32] of TSDL_Rect =
@@ -542,9 +542,9 @@
        (x: 3598; y: 1424; w:   42; h:    2),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template18FPoints: array[0..0] of TPoint =
+      Template18FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 2047; Y:    0)
+       (X: 2047; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template19Points: array[0..44] of TSDL_Rect =
@@ -595,9 +595,9 @@
        (x: 3398; y: 1424; w:   52; h:    2),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template19FPoints: array[0..0] of TPoint =
+      Template19FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 2047; Y:    0)
+       (X: 2047; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template20Points: array[0..45] of TSDL_Rect =
@@ -649,9 +649,9 @@
        (x: 3456; y: 1424; w:    2; h:    2),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template20FPoints: array[0..0] of TPoint =
+      Template20FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 2047; Y:    0)
+       (X: 2047; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template21Points: array[0..30] of TSDL_Rect =
@@ -688,9 +688,9 @@
        (x: 3258; y: 1424; w:    2; h:    2),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template21FPoints: array[0..0] of TPoint =
+      Template21FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 2047; Y:    0)
+       (X: 2047; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template22Points: array[0..38] of TSDL_Rect =
@@ -735,9 +735,9 @@
        (x: 3244; y: 1424; w:    2; h:    2),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template22FPoints: array[0..0] of TPoint =
+      Template22FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 2047; Y:    0)
+       (X: 2047; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template23Points: array[0..29] of TSDL_Rect =
@@ -773,9 +773,9 @@
        (x: 3438; y: 1424; w:  176; h:    1),
        (x: NTPX; y:    0; w:    1; h:    1)
        );
-      Template23FPoints: array[0..0] of TPoint =
+      Template23FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 2047; Y:    0)
+       (X: 2047; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template24Points: array[0..23] of TSDL_Rect =
@@ -805,9 +805,9 @@
        (x: 3346; y: 1420; w:    2; h:    2),
        (x: NTPX; y:    0; w:    1; h:    1)
        );
-      Template24FPoints: array[0..0] of TPoint =
+      Template24FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 2047; Y:    0)
+       (X: 2047; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template25Points: array[0..19] of TSDL_Rect =
@@ -833,9 +833,9 @@
        (x: 3532; y: 1424; w:    2; h:    1),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template25FPoints: array[0..0] of TPoint =
+      Template25FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 2047; Y:    0)
+       (X: 2047; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 
@@ -894,9 +894,9 @@
        (x: 3480; y: 1424; w:    1; h:    1),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template26FPoints: array[0..0] of TPoint =
+      Template26FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 2047; Y:    0)
+       (X: 2047; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template27Points: array[0..42] of TSDL_Rect =
@@ -945,9 +945,9 @@
        (x: 3556; y: 1424; w:    2; h:    2),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template27FPoints: array[0..0] of TPoint =
+      Template27FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 2047; Y:    0)
+       (X: 2047; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template28Points: array[0..29] of TSDL_Rect =
@@ -983,9 +983,9 @@
        (x: 3308; y: 1424; w:    2; h:    2),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template28FPoints: array[0..0] of TPoint =
+      Template28FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 2047; Y:    0)
+       (X: 2047; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template29Points: array[0..37] of TSDL_Rect =
@@ -1029,9 +1029,9 @@
        (x: 3094; y: 1424; w:    2; h:    2),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template29FPoints: array[0..0] of TPoint =
+      Template29FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 2047; Y:    0)
+       (X: 2047; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template30Points: array[0..30] of TSDL_Rect =
@@ -1068,9 +1068,9 @@
        (x: 3288; y: 1424; w:  176; h:    1),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template30FPoints: array[0..0] of TPoint =
+      Template30FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 2047; Y:    0)
+       (X: 2047; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template31Points: array[0..32] of TSDL_Rect =
@@ -1109,9 +1109,9 @@
        (x: 3584; y: 1424; w:  136; h:    1),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template31FPoints: array[0..0] of TPoint =
+      Template31FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 2047; Y:    0)
+       (X: 2047; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template32Points: array[0..29] of TSDL_Rect =
@@ -1147,9 +1147,9 @@
        (x: 3682; y: 1424; w:    2; h:    1),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template32FPoints: array[0..0] of TPoint =
+      Template32FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-         (X: 2047; Y:    0)
+       (X: 2047; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template33Points: array[0..45] of TSDL_Rect =
@@ -1201,9 +1201,9 @@
        (x: 3480; y: 1424; w:    1; h:    1),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template33FPoints: array[0..0] of TPoint =
+      Template33FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 2047; Y:    0)
+       (X: 2047; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template34Points: array[0..25] of TSDL_Rect =
@@ -1235,9 +1235,9 @@
        (x: 3230; y: 1424; w:   20; h:    1),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template34FPoints: array[0..0] of TPoint =
+      Template34FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 2047; Y:    0)
+       (X: 2047; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 const Template35Points: array[0..48] of TSDL_Rect =
@@ -1292,9 +1292,9 @@
        (x: 3498; y: 1424; w:   52; h:    2),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template35FPoints: array[0..0] of TPoint =
+      Template35FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 2047; Y:    0)
+       (X: 2047; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 ///////////////////////// CAVERNS ///////////////////////////////////
@@ -1320,9 +1320,9 @@
        (x:  576; y:  976; w:   16; h:   28),
        (x: NTPX; y:    0; w:    1; h:    1)
       );
-      Template36FPoints: array[0..0] of TPoint =
+      Template36FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 2047; Y:    0)
+       (X: 2047; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 ////////////////////////////// ... Silly ...  ////////////////////////////////
 /// Ok. Tiy does not care for these.  Perhaps they could be saved.
@@ -1361,9 +1361,9 @@
        (x: 2250; y: 1200; w: 25; h: 25),
        (x: NTPX; y:    0; w:  1; h:  1)
       );
-      Template37FPoints: array[0..0] of TPoint =
+      Template37FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 2047; Y:    0)
+       (X: 2047; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 // attempt to make a series of moderate hills/valleys - was before I really figured out the whole probabilities thing
 const Template38Points: array[0..16] of TSDL_Rect =
@@ -1386,9 +1386,9 @@
        (x: 3700; y: 2100; w:   1; h:    1),
        (x: NTPX; y:    0; w:   1; h:    1)
       );
-      Template38FPoints: array[0..0] of TPoint =
+      Template38FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 2047; Y:    0)
+       (X: 2047; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 // 8 tiny islands
@@ -1435,9 +1435,9 @@
        (x: 1430; y: 520; w:   1; h:   1),
        (x: NTPX; y:   0; w:   1; h:   1)
       );
-      Template39FPoints: array[0..0] of TPoint =
+      Template39FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 512; Y:    0)
+       (X: 512; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 const Template40Points: array[0..7] of TSDL_Rect =
       (
@@ -1450,9 +1450,9 @@
        (x:  900; y: 1050; w:    1; h:   1),
        (x: NTPX; y:    0; w:    1; h:   1)
       );
-      Template40FPoints: array[0..0] of TPoint =
+      Template40FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 512; Y:    0)
+       (X: 512; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 // Many islands
 const Template41Points: array[0..86] of TSDL_Rect =
@@ -1545,9 +1545,9 @@
        (x: 4050; y: 125; w:  50; h:  75),
        (x: NTPX; y:   0; w:   1; h:   1)
       );
-      Template41FPoints: array[0..0] of TPoint =
+      Template41FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 2047; Y:    0)
+       (X: 2047; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 // 2 tiny islands
 const Template42Points: array[0..13] of TSDL_Rect =
@@ -1567,9 +1567,9 @@
        (x: 1430; y: 520; w:   1; h:   1),
        (x: NTPX; y:   0; w:   1; h:   1)
       );
-      Template42FPoints: array[0..0] of TPoint =
+      Template42FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 512; Y:    0)
+       (X: 512; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 // Many islands
 const Template43Points: array[0..173] of TSDL_Rect =
@@ -1749,9 +1749,9 @@
        (x: 4050; y:2173; w:  50; h:  75),
        (x: NTPX; y:2048; w:   1; h:   1)
       );
-      Template43FPoints: array[0..0] of TPoint =
+      Template43FPoints: array[0..{$IFDEF PAS2C}1{$ELSE}0{$ENDIF}] of TPoint =
       (
-       (X: 4095; Y:    0)
+       (X: 4095; Y:    0){$IFDEF PAS2C},(X:0;Y:9){$ENDIF}
       );
 
 // 3 large caverns
@@ -1775,12 +1775,12 @@
       );
       Template44FPoints: array[0..5] of TSDL_Rect =
       (
-       (X:   1; Y:  90; w:   0; h:   0),
-       (X:   1; Y: 500; w:   0; h:   0),
-       (X:4095; Y: 500; w:   0; h:   0),
-       (X:   1; Y:1200; w:   0; h:   0),
-       (X:4095; Y:1200; w:   0; h:   0),
-       (X:   1; Y:2010; w:   0; h:   0)
+       (x:   1; y:  90; w:   0; h:   0),
+       (x:   1; y: 500; w:   0; h:   0),
+       (x:4095; y: 500; w:   0; h:   0),
+       (x:   1; y:1200; w:   0; h:   0),
+       (x:4095; y:1200; w:   0; h:   0),
+       (x:   1; y:2010; w:   0; h:   0)
       );
 
 // large caverns with an island
@@ -1801,9 +1801,9 @@
       );
       Template45FPoints: array[0..2] of TSDL_Rect =
       (
-       (X:   1; Y:   1; w:   0; h:   0),
-       (X:   1; Y:2047; w:   0; h:   0),
-       (X:1005; Y: 805; w:   0; h:   0)
+       (x:   1; y:   1; w:   0; h:   0),
+       (x:   1; y:2047; w:   0; h:   0),
+       (x:1005; y: 805; w:   0; h:   0)
       );
 
 ////////////////////////////////////////////////////////////////////////
@@ -1812,7 +1812,7 @@
        (BasePoints: @Template0Points;
         BasePointsCount: Succ(High(Template0Points));
         FillPoints: @Template0FPoints;
-        FillPointsCount: Succ(High(Template0FPoints));
+        FillPointsCount: Succ(High(Template0FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 3;
         RandPassesCount: 8;
         TemplateHeight: 1424; TemplateWidth: 3072;
@@ -1823,7 +1823,7 @@
        (BasePoints: @Template1Points;
         BasePointsCount: Succ(High(Template1Points));
         FillPoints: @Template1FPoints;
-        FillPointsCount: Succ(High(Template1FPoints));
+        FillPointsCount: Succ(High(Template1FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 3;
         RandPassesCount: 7;
         TemplateHeight: 1424; TemplateWidth: 3072;
@@ -1834,7 +1834,7 @@
        (BasePoints: @Template2Points;
         BasePointsCount: Succ(High(Template2Points));
         FillPoints: @Template2FPoints;
-        FillPointsCount: Succ(High(Template2FPoints));
+        FillPointsCount: Succ(High(Template2FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 2;
         RandPassesCount: 6;
         TemplateHeight: 1424; TemplateWidth: 3072;
@@ -1845,7 +1845,7 @@
        (BasePoints: @Template3Points;
         BasePointsCount: Succ(High(Template3Points));
         FillPoints: @Template3FPoints;
-        FillPointsCount: Succ(High(Template3FPoints));
+        FillPointsCount: Succ(High(Template3FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 3;
         RandPassesCount: 4;
         TemplateHeight: 1424; TemplateWidth: 3072;
@@ -1856,7 +1856,7 @@
        (BasePoints: @Template4Points;
         BasePointsCount: Succ(High(Template4Points));
         FillPoints: @Template4FPoints;
-        FillPointsCount: Succ(High(Template4FPoints));
+        FillPointsCount: Succ(High(Template4FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 3;
         RandPassesCount: 4;
         TemplateHeight: 1424; TemplateWidth: 3072;
@@ -1867,7 +1867,7 @@
        (BasePoints: @Template5Points;
         BasePointsCount: Succ(High(Template5Points));
         FillPoints: @Template5FPoints;
-        FillPointsCount: Succ(High(Template5FPoints));
+        FillPointsCount: Succ(High(Template5FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 2;
         RandPassesCount: 8;
         TemplateHeight: 1424; TemplateWidth: 3072;
@@ -1878,7 +1878,7 @@
        (BasePoints: @Template6Points;
         BasePointsCount: Succ(High(Template6Points));
         FillPoints: @Template6FPoints;
-        FillPointsCount: Succ(High(Template6FPoints));
+        FillPointsCount: Succ(High(Template6FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 2;
         RandPassesCount: 5;
         TemplateHeight: 1424; TemplateWidth: 3072;
@@ -1889,7 +1889,7 @@
        (BasePoints: @Template7Points;
         BasePointsCount: Succ(High(Template7Points));
         FillPoints: @Template7FPoints;
-        FillPointsCount: Succ(High(Template7FPoints));
+        FillPointsCount: Succ(High(Template7FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 4;
         RandPassesCount: 4;
         TemplateHeight: 1424; TemplateWidth: 3072;
@@ -1900,7 +1900,7 @@
        (BasePoints: @Template8Points;
         BasePointsCount: Succ(High(Template8Points));
         FillPoints: @Template8FPoints;
-        FillPointsCount: Succ(High(Template8FPoints));
+        FillPointsCount: Succ(High(Template8FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 2;
         RandPassesCount: 7;
         TemplateHeight: 1424; TemplateWidth: 3072;
@@ -1911,7 +1911,7 @@
        (BasePoints: @Template9Points;
         BasePointsCount: Succ(High(Template9Points));
         FillPoints: @Template9FPoints;
-        FillPointsCount: Succ(High(Template9FPoints));
+        FillPointsCount: Succ(High(Template9FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 1;
         RandPassesCount: 5;
         TemplateHeight: 1424; TemplateWidth: 3072;
@@ -1922,7 +1922,7 @@
        (BasePoints: @Template10Points;
         BasePointsCount: Succ(High(Template10Points));
         FillPoints: @Template10FPoints;
-        FillPointsCount: Succ(High(Template10FPoints));
+        FillPointsCount: Succ(High(Template10FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 2;
         RandPassesCount: 6;
         TemplateHeight: 1424; TemplateWidth: 3072;
@@ -1933,7 +1933,7 @@
        (BasePoints: @Template11Points;
         BasePointsCount: Succ(High(Template11Points));
         FillPoints: @Template11FPoints;
-        FillPointsCount: Succ(High(Template11FPoints));
+        FillPointsCount: Succ(High(Template11FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 1;
         RandPassesCount: 8;
         TemplateHeight: 1424; TemplateWidth: 3072;
@@ -1944,7 +1944,7 @@
        (BasePoints: @Template12Points;
         BasePointsCount: Succ(High(Template12Points));
         FillPoints: @Template12FPoints;
-        FillPointsCount: Succ(High(Template12FPoints));
+        FillPointsCount: Succ(High(Template12FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 3;
         RandPassesCount: 8;
         TemplateHeight: 1424; TemplateWidth: 3072;
@@ -1955,7 +1955,7 @@
        (BasePoints: @Template13Points;
         BasePointsCount: Succ(High(Template13Points));
         FillPoints: @Template13FPoints;
-        FillPointsCount: Succ(High(Template13FPoints));
+        FillPointsCount: Succ(High(Template13FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 3;
         RandPassesCount: 5;
         TemplateHeight: 1424; TemplateWidth: 3072;
@@ -1966,7 +1966,7 @@
        (BasePoints: @Template14Points;
         BasePointsCount: Succ(High(Template14Points));
         FillPoints: @Template14FPoints;
-        FillPointsCount: Succ(High(Template14FPoints));
+        FillPointsCount: Succ(High(Template14FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 3;
         RandPassesCount: 7;
         TemplateHeight: 1424; TemplateWidth: 3072;
@@ -1977,7 +1977,7 @@
        (BasePoints: @Template15Points;
         BasePointsCount: Succ(High(Template15Points));
         FillPoints: @Template15FPoints;
-        FillPointsCount: Succ(High(Template15FPoints));
+        FillPointsCount: Succ(High(Template15FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 2;
         RandPassesCount: 6;
         TemplateHeight: 1424; TemplateWidth: 3072;
@@ -1988,7 +1988,7 @@
        (BasePoints: @Template16Points;
         BasePointsCount: Succ(High(Template16Points));
         FillPoints: @Template16FPoints;
-        FillPointsCount: Succ(High(Template16FPoints));
+        FillPointsCount: Succ(High(Template16FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 2;
         RandPassesCount: 6;
         TemplateHeight: 1424; TemplateWidth: 3072;
@@ -1999,7 +1999,7 @@
        (BasePoints: @Template17Points;
         BasePointsCount: Succ(High(Template17Points));
         FillPoints: @Template17FPoints;
-        FillPointsCount: Succ(High(Template17FPoints));
+        FillPointsCount: Succ(High(Template17FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 3;
         RandPassesCount: 7;
         TemplateHeight: 1424; TemplateWidth: 3072;
@@ -2010,7 +2010,7 @@
        (BasePoints: @Template18Points;
         BasePointsCount: Succ(High(Template18Points));
         FillPoints: @Template18FPoints;
-        FillPointsCount: Succ(High(Template18FPoints));
+        FillPointsCount: Succ(High(Template18FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 3;
         RandPassesCount: 8;
         TemplateHeight: 1424; TemplateWidth: 4096;
@@ -2021,7 +2021,7 @@
        (BasePoints: @Template19Points;
         BasePointsCount: Succ(High(Template19Points));
         FillPoints: @Template19FPoints;
-        FillPointsCount: Succ(High(Template19FPoints));
+        FillPointsCount: Succ(High(Template19FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 3;
         RandPassesCount: 7;
         TemplateHeight: 1424; TemplateWidth: 4096;
@@ -2032,7 +2032,7 @@
        (BasePoints: @Template20Points;
         BasePointsCount: Succ(High(Template20Points));
         FillPoints: @Template20FPoints;
-        FillPointsCount: Succ(High(Template20FPoints));
+        FillPointsCount: Succ(High(Template20FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 2;
         RandPassesCount: 6;
         TemplateHeight: 1424; TemplateWidth: 4096;
@@ -2043,7 +2043,7 @@
        (BasePoints: @Template21Points;
         BasePointsCount: Succ(High(Template21Points));
         FillPoints: @Template21FPoints;
-        FillPointsCount: Succ(High(Template21FPoints));
+        FillPointsCount: Succ(High(Template21FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 3;
         RandPassesCount: 4;
         TemplateHeight: 1424; TemplateWidth: 4096;
@@ -2054,7 +2054,7 @@
        (BasePoints: @Template22Points;
         BasePointsCount: Succ(High(Template22Points));
         FillPoints: @Template22FPoints;
-        FillPointsCount: Succ(High(Template22FPoints));
+        FillPointsCount: Succ(High(Template22FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 3;
         RandPassesCount: 4;
         TemplateHeight: 1424; TemplateWidth: 4096;
@@ -2065,7 +2065,7 @@
        (BasePoints: @Template23Points;
         BasePointsCount: Succ(High(Template23Points));
         FillPoints: @Template23FPoints;
-        FillPointsCount: Succ(High(Template23FPoints));
+        FillPointsCount: Succ(High(Template23FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 2;
         RandPassesCount: 8;
         TemplateHeight: 1424; TemplateWidth: 4096;
@@ -2076,7 +2076,7 @@
        (BasePoints: @Template24Points;
         BasePointsCount: Succ(High(Template24Points));
         FillPoints: @Template24FPoints;
-        FillPointsCount: Succ(High(Template24FPoints));
+        FillPointsCount: Succ(High(Template24FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 2;
         RandPassesCount: 5;
         TemplateHeight: 1424; TemplateWidth: 4096;
@@ -2087,7 +2087,7 @@
        (BasePoints: @Template25Points;
         BasePointsCount: Succ(High(Template25Points));
         FillPoints: @Template25FPoints;
-        FillPointsCount: Succ(High(Template25FPoints));
+        FillPointsCount: Succ(High(Template25FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 4;
         RandPassesCount: 4;
         TemplateHeight: 1424; TemplateWidth: 4096;
@@ -2098,7 +2098,7 @@
        (BasePoints: @Template26Points;
         BasePointsCount: Succ(High(Template26Points));
         FillPoints: @Template26FPoints;
-        FillPointsCount: Succ(High(Template26FPoints));
+        FillPointsCount: Succ(High(Template26FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 2;
         RandPassesCount: 7;
         TemplateHeight: 1424; TemplateWidth: 4096;
@@ -2109,7 +2109,7 @@
        (BasePoints: @Template27Points;
         BasePointsCount: Succ(High(Template27Points));
         FillPoints: @Template27FPoints;
-        FillPointsCount: Succ(High(Template27FPoints));
+        FillPointsCount: Succ(High(Template27FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 1;
         RandPassesCount: 5;
         TemplateHeight: 1424; TemplateWidth: 4096;
@@ -2120,7 +2120,7 @@
        (BasePoints: @Template28Points;
         BasePointsCount: Succ(High(Template28Points));
         FillPoints: @Template28FPoints;
-        FillPointsCount: Succ(High(Template28FPoints));
+        FillPointsCount: Succ(High(Template28FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 2;
         RandPassesCount: 6;
         TemplateHeight: 1424; TemplateWidth: 4096;
@@ -2131,7 +2131,7 @@
        (BasePoints: @Template29Points;
         BasePointsCount: Succ(High(Template29Points));
         FillPoints: @Template29FPoints;
-        FillPointsCount: Succ(High(Template29FPoints));
+        FillPointsCount: Succ(High(Template29FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 1;
         RandPassesCount: 8;
         TemplateHeight: 1424; TemplateWidth: 4096;
@@ -2142,7 +2142,7 @@
        (BasePoints: @Template30Points;
         BasePointsCount: Succ(High(Template30Points));
         FillPoints: @Template30FPoints;
-        FillPointsCount: Succ(High(Template30FPoints));
+        FillPointsCount: Succ(High(Template30FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 3;
         RandPassesCount: 8;
         TemplateHeight: 1424; TemplateWidth: 4096;
@@ -2153,7 +2153,7 @@
        (BasePoints: @Template31Points;
         BasePointsCount: Succ(High(Template31Points));
         FillPoints: @Template31FPoints;
-        FillPointsCount: Succ(High(Template31FPoints));
+        FillPointsCount: Succ(High(Template31FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 3;
         RandPassesCount: 5;
         TemplateHeight: 1424; TemplateWidth: 4096;
@@ -2164,7 +2164,7 @@
        (BasePoints: @Template32Points;
         BasePointsCount: Succ(High(Template32Points));
         FillPoints: @Template32FPoints;
-        FillPointsCount: Succ(High(Template32FPoints));
+        FillPointsCount: Succ(High(Template32FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 3;
         RandPassesCount: 7;
         TemplateHeight: 1424; TemplateWidth: 4096;
@@ -2175,7 +2175,7 @@
        (BasePoints: @Template33Points;
         BasePointsCount: Succ(High(Template33Points));
         FillPoints: @Template33FPoints;
-        FillPointsCount: Succ(High(Template33FPoints));
+        FillPointsCount: Succ(High(Template33FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 2;
         RandPassesCount: 6;
         TemplateHeight: 1424; TemplateWidth: 4096;
@@ -2186,7 +2186,7 @@
        (BasePoints: @Template34Points;
         BasePointsCount: Succ(High(Template34Points));
         FillPoints: @Template34FPoints;
-        FillPointsCount: Succ(High(Template34FPoints));
+        FillPointsCount: Succ(High(Template34FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 2;
         RandPassesCount: 6;
         TemplateHeight: 1424; TemplateWidth: 4096;
@@ -2197,7 +2197,7 @@
        (BasePoints: @Template35Points;
         BasePointsCount: Succ(High(Template35Points));
         FillPoints: @Template35FPoints;
-        FillPointsCount: Succ(High(Template35FPoints));
+        FillPointsCount: Succ(High(Template35FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 3;
         RandPassesCount: 7;
         TemplateHeight: 1424; TemplateWidth: 4096;
@@ -2208,7 +2208,7 @@
        (BasePoints: @Template36Points;
         BasePointsCount: Succ(High(Template36Points));
         FillPoints: @Template36FPoints;
-        FillPointsCount: Succ(High(Template36FPoints));
+        FillPointsCount: Succ(High(Template36FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 4;
         RandPassesCount: 12;
         TemplateHeight: 1024; TemplateWidth: 4096;
@@ -2219,7 +2219,7 @@
        (BasePoints: @Template37Points;
         BasePointsCount: Succ(High(Template37Points));
         FillPoints: @Template37FPoints;
-        FillPointsCount: Succ(High(Template37FPoints));
+        FillPointsCount: Succ(High(Template37FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 3;
         RandPassesCount: 3;
         TemplateHeight: 2048; TemplateWidth: 4096;
@@ -2230,7 +2230,7 @@
        (BasePoints: @Template38Points;
         BasePointsCount: Succ(High(Template38Points));
         FillPoints: @Template38FPoints;
-        FillPointsCount: Succ(High(Template38FPoints));
+        FillPointsCount: Succ(High(Template38FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 4;
         RandPassesCount: 4;
         TemplateHeight: 2048; TemplateWidth: 4096;
@@ -2241,7 +2241,7 @@
        (BasePoints: @Template39Points;
         BasePointsCount: Succ(High(Template39Points));
         FillPoints: @Template39FPoints;
-        FillPointsCount: Succ(High(Template39FPoints));
+        FillPointsCount: Succ(High(Template39FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 3;
         RandPassesCount: 3;
         TemplateHeight: 512; TemplateWidth: 1536;
@@ -2252,7 +2252,7 @@
        (BasePoints: @Template40Points;
         BasePointsCount: Succ(High(Template40Points));
         FillPoints: @Template40FPoints;
-        FillPointsCount: Succ(High(Template40FPoints));
+        FillPointsCount: Succ(High(Template40FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 3;
         RandPassesCount: 3;
         TemplateHeight: 1024; TemplateWidth: 1024;
@@ -2263,7 +2263,7 @@
        (BasePoints: @Template41Points;
         BasePointsCount: Succ(High(Template41Points));
         FillPoints: @Template41FPoints;
-        FillPointsCount: Succ(High(Template41FPoints));
+        FillPointsCount: Succ(High(Template41FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 2;
         RandPassesCount: 9;
         TemplateHeight: 2048; TemplateWidth: 4096;
@@ -2274,7 +2274,7 @@
        (BasePoints: @Template42Points;
         BasePointsCount: Succ(High(Template42Points));
         FillPoints: @Template42FPoints;
-        FillPointsCount: Succ(High(Template42FPoints));
+        FillPointsCount: Succ(High(Template42FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 3;
         RandPassesCount: 3;
         TemplateHeight: 512; TemplateWidth: 1536;
@@ -2285,7 +2285,7 @@
        (BasePoints: @Template43Points;
         BasePointsCount: Succ(High(Template43Points));
         FillPoints: @Template43FPoints;
-        FillPointsCount: Succ(High(Template43FPoints));
+        FillPointsCount: Succ(High(Template43FPoints)){$IFDEF PAS2C}-1{$ENDIF};
         BezierizeCount: 2;
         RandPassesCount: 9;
         TemplateHeight: 4096; TemplateWidth: 4096;
--- a/hedgewars/uLandTexture.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uLandTexture.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -39,10 +39,11 @@
             tex: PTexture;
             end;
 
-var LandTextures: array of array of TLandRecord;
-    tmpPixels: array [0..TEXSIZE - 1, 0..TEXSIZE - 1] of LongWord;
-    LANDTEXARW: LongWord;
-    LANDTEXARH: LongWord;
+var
+    LandTextures : array of array of TLandRecord;
+    tmpPixels	 : array [0..TEXSIZE - 1, 0..TEXSIZE - 1] of LongWord;
+    LANDTEXARW	 : LongWord;
+    LANDTEXARH	 : LongWord;
 
 function Pixels(x, y: Longword): Pointer;
 var ty: Longword;
@@ -198,7 +199,6 @@
         LANDTEXARW:= (LAND_WIDTH div TEXSIZE) div 2;
         LANDTEXARH:= (LAND_HEIGHT div TEXSIZE) div 2;
         end;
-
     SetLength(LandTextures, LANDTEXARW, LANDTEXARH);
 end;
 
--- a/hedgewars/uLocale.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uLocale.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -62,10 +62,10 @@
         if (s[1] < '0') or (s[1] > '9') then
             continue;
         TryDo(Length(s) > 6, 'Load locale: empty string', true);
-        val(s[1]+s[2], a, c);
+        val(s[1]+s[2], a{$IFNDEF PAS2C}, c{$ENDIF});
         TryDo(c = 0, 'Load locale: numbers should be two-digit: ' + s, true);
         TryDo(s[3] = ':', 'Load locale: ":" expected', true);
-        val(s[4]+s[5], b, c);
+        val(s[4]+s[5], b{$IFNDEF PAS2C}, c{$ENDIF});
         TryDo(c = 0, 'Load locale: numbers should be two-digit' + s, true);
         TryDo(s[6] = '=', 'Load locale: "=" expected', true);
         Delete(s, 1, 6);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/uMatrix.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,268 @@
+(*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *)
+
+{$INCLUDE "options.inc"}
+
+unit uMatrix;
+
+interface
+
+uses uTypes {$IFNDEF PAS2C}, gl{$ENDIF};
+
+const
+    MATRIX_MODELVIEW:Integer = 0;
+    MATRIX_PROJECTION:Integer = 1;
+  
+procedure MatrixLoadIdentity(out Result: TMatrix4x4f);
+procedure MatrixMultiply(out Result: TMatrix4x4f; const lhs, rhs: TMatrix4x4f);
+
+procedure hglMatrixMode(t: Integer);
+procedure hglLoadIdentity();
+procedure hglPushMatrix();
+procedure hglPopMatrix();
+procedure hglMVP(var res : TMatrix4x4f);
+procedure hglScalef(x: GLfloat; y: GLfloat; z: GLfloat);
+procedure hglTranslatef(x: GLfloat; y: GLfloat; z: GLfloat);
+procedure hglRotatef(a:GLfloat; x:GLfloat; y:GLfloat; z:GLfloat);
+procedure initModule();
+procedure freeModule();
+
+implementation
+
+const
+    MATRIX_STACK_SIZE = 10;
+
+type
+    TMatrixStack = record
+        top:Integer;
+        stack: array[0..9] of TMatrix4x4f;
+        end;
+var
+    MatrixStacks : array[0..1] of TMatrixStack;
+    CurMatrix: integer;
+
+procedure MatrixLoadIdentity(out Result: TMatrix4x4f);
+begin
+    Result[0,0]:= 1.0; Result[1,0]:=0.0; Result[2,0]:=0.0; Result[3,0]:=0.0;
+    Result[0,1]:= 0.0; Result[1,1]:=1.0; Result[2,1]:=0.0; Result[3,1]:=0.0;
+    Result[0,2]:= 0.0; Result[1,2]:=0.0; Result[2,2]:=1.0; Result[3,2]:=0.0;
+    Result[0,3]:= 0.0; Result[1,3]:=0.0; Result[2,3]:=0.0; Result[3,3]:=1.0;
+end;
+
+procedure hglMatrixMode(t: Integer);
+begin
+    CurMatrix := t;
+end;
+
+procedure hglLoadIdentity();
+begin
+    MatrixLoadIdentity(MatrixStacks[CurMatrix].stack[MatrixStacks[CurMatrix].top]);
+end;
+
+procedure hglScalef(x: GLfloat; y: GLfloat; z: GLfloat);
+var
+    m:TMatrix4x4f;
+    t:TMatrix4x4f;
+begin
+    m[0,0]:=x;m[1,0]:=0;m[2,0]:=0;m[3,0]:=0;
+    m[0,1]:=0;m[1,1]:=y;m[2,1]:=0;m[3,1]:=0;
+    m[0,2]:=0;m[1,2]:=0;m[2,2]:=z;m[3,2]:=0;
+    m[0,3]:=0;m[1,3]:=0;m[2,3]:=0;m[3,3]:=1;
+
+    MatrixMultiply(t, MatrixStacks[CurMatrix].stack[MatrixStacks[CurMatrix].top], m);
+    MatrixStacks[CurMatrix].stack[MatrixStacks[CurMatrix].top] := t; 
+end;
+
+procedure hglTranslatef(x: GLfloat; y: GLfloat; z: GLfloat);
+var
+    m:TMatrix4x4f;
+    t:TMatrix4x4f;
+begin
+    m[0,0]:=1;m[1,0]:=0;m[2,0]:=0;m[3,0]:=x;
+    m[0,1]:=0;m[1,1]:=1;m[2,1]:=0;m[3,1]:=y;
+    m[0,2]:=0;m[1,2]:=0;m[2,2]:=1;m[3,2]:=z;
+    m[0,3]:=0;m[1,3]:=0;m[2,3]:=0;m[3,3]:=1;
+
+    MatrixMultiply(t, MatrixStacks[CurMatrix].stack[MatrixStacks[CurMatrix].top], m);
+    MatrixStacks[CurMatrix].stack[MatrixStacks[CurMatrix].top] := t;
+end;
+
+procedure hglRotatef(a:GLfloat; x:GLfloat; y:GLfloat; z:GLfloat);
+var
+    m:TMatrix4x4f;
+    t:TMatrix4x4f;
+    c:GLfloat;
+    s:GLfloat;
+    xn, yn, zn:GLfloat;
+    l:GLfloat;
+begin
+    a:=a * 3.14159265368 / 180;
+    c:=cos(a);
+    s:=sin(a);
+    
+    l := 1.0 / sqrt(x * x + y * y + z * z);
+    xn := x * l;
+    yn := y * l;
+    zn := z * l;
+
+    m[0,0]:=c + xn * xn * (1 - c);
+    m[1,0]:=xn * yn * (1 - c) - zn * s;
+    m[2,0]:=xn * zn * (1 - c) + yn * s;
+    m[3,0]:=0;
+
+
+    m[0,1]:=yn * xn * (1 - c) + zn * s;
+    m[1,1]:=c + yn * yn * (1 - c);
+    m[2,1]:=yn * zn * (1 - c) - xn * s;
+    m[3,1]:=0;
+
+    m[0,2]:=zn * xn * (1 - c) - yn * s;
+    m[1,2]:=zn * yn * (1 - c) + xn * s;
+    m[2,2]:=c + zn * zn * (1 - c);
+    m[3,2]:=0;
+
+    m[0,3]:=0;m[1,3]:=0;m[2,3]:=0;m[3,3]:=1;
+
+    MatrixMultiply(t, MatrixStacks[CurMatrix].stack[MatrixStacks[CurMatrix].top], m);
+    MatrixStacks[CurMatrix].stack[MatrixStacks[CurMatrix].top] := t;
+end;
+
+procedure hglMVP(var res: TMatrix4x4f);
+begin
+    MatrixMultiply(res, 
+                   MatrixStacks[MATRIX_PROJECTION].stack[MatrixStacks[MATRIX_PROJECTION].top], 
+                   MatrixStacks[MATRIX_MODELVIEW].stack[MatrixStacks[MATRIX_MODELVIEW].top]);
+end;
+
+procedure hglPushMatrix();
+var
+    t: Integer;
+begin
+    t := MatrixStacks[CurMatrix].top;
+    MatrixStacks[CurMatrix].stack[t + 1] := MatrixStacks[CurMatrix].stack[t];
+    inc(t);
+    MatrixStacks[CurMatrix].top := t;
+end;
+
+procedure hglPopMatrix();
+var
+    t: Integer;
+begin
+    t := MatrixStacks[CurMatrix].top;
+    dec(t);
+    MatrixStacks[CurMatrix].top := t;
+end;
+
+procedure initModule();
+begin
+    MatrixStacks[MATRIX_MODELVIEW].top := 0;
+    MatrixStacks[MATRIX_Projection].top := 0;
+    MatrixLoadIdentity(MatrixStacks[MATRIX_MODELVIEW].stack[0]);
+    MatrixLoadIdentity(MatrixStacks[MATRIX_PROJECTION].stack[0]);
+end;
+
+procedure freeModule();
+begin
+end;
+
+procedure MatrixMultiply(out Result: TMatrix4x4f; const lhs, rhs: TMatrix4x4f);
+var
+    test: TMatrix4x4f;
+    i, j: Integer;
+    error: boolean;
+begin
+    Result[0,0]:=lhs[0,0]*rhs[0,0] + lhs[1,0]*rhs[0,1] + lhs[2,0]*rhs[0,2] + lhs[3,0]*rhs[0,3];
+    Result[0,1]:=lhs[0,1]*rhs[0,0] + lhs[1,1]*rhs[0,1] + lhs[2,1]*rhs[0,2] + lhs[3,1]*rhs[0,3];
+    Result[0,2]:=lhs[0,2]*rhs[0,0] + lhs[1,2]*rhs[0,1] + lhs[2,2]*rhs[0,2] + lhs[3,2]*rhs[0,3];
+    Result[0,3]:=lhs[0,3]*rhs[0,0] + lhs[1,3]*rhs[0,1] + lhs[2,3]*rhs[0,2] + lhs[3,3]*rhs[0,3];
+
+    Result[1,0]:=lhs[0,0]*rhs[1,0] + lhs[1,0]*rhs[1,1] + lhs[2,0]*rhs[1,2] + lhs[3,0]*rhs[1,3];
+    Result[1,1]:=lhs[0,1]*rhs[1,0] + lhs[1,1]*rhs[1,1] + lhs[2,1]*rhs[1,2] + lhs[3,1]*rhs[1,3];
+    Result[1,2]:=lhs[0,2]*rhs[1,0] + lhs[1,2]*rhs[1,1] + lhs[2,2]*rhs[1,2] + lhs[3,2]*rhs[1,3];
+    Result[1,3]:=lhs[0,3]*rhs[1,0] + lhs[1,3]*rhs[1,1] + lhs[2,3]*rhs[1,2] + lhs[3,3]*rhs[1,3];
+
+    Result[2,0]:=lhs[0,0]*rhs[2,0] + lhs[1,0]*rhs[2,1] + lhs[2,0]*rhs[2,2] + lhs[3,0]*rhs[2,3];
+    Result[2,1]:=lhs[0,1]*rhs[2,0] + lhs[1,1]*rhs[2,1] + lhs[2,1]*rhs[2,2] + lhs[3,1]*rhs[2,3];
+    Result[2,2]:=lhs[0,2]*rhs[2,0] + lhs[1,2]*rhs[2,1] + lhs[2,2]*rhs[2,2] + lhs[3,2]*rhs[2,3];
+    Result[2,3]:=lhs[0,3]*rhs[2,0] + lhs[1,3]*rhs[2,1] + lhs[2,3]*rhs[2,2] + lhs[3,3]*rhs[2,3];
+
+    Result[3,0]:=lhs[0,0]*rhs[3,0] + lhs[1,0]*rhs[3,1] + lhs[2,0]*rhs[3,2] + lhs[3,0]*rhs[3,3];
+    Result[3,1]:=lhs[0,1]*rhs[3,0] + lhs[1,1]*rhs[3,1] + lhs[2,1]*rhs[3,2] + lhs[3,1]*rhs[3,3];
+    Result[3,2]:=lhs[0,2]*rhs[3,0] + lhs[1,2]*rhs[3,1] + lhs[2,2]*rhs[3,2] + lhs[3,2]*rhs[3,3];
+    Result[3,3]:=lhs[0,3]*rhs[3,0] + lhs[1,3]*rhs[3,1] + lhs[2,3]*rhs[3,2] + lhs[3,3]*rhs[3,3];
+
+{
+    Result[0,0]:=lhs[0,0]*rhs[0,0] + lhs[1,0]*rhs[0,1] + lhs[2,0]*rhs[0,2] + lhs[3,0]*rhs[0,3];
+    Result[0,1]:=lhs[0,0]*rhs[1,0] + lhs[1,0]*rhs[1,1] + lhs[2,0]*rhs[1,2] + lhs[3,0]*rhs[1,3];
+    Result[0,2]:=lhs[0,0]*rhs[2,0] + lhs[1,0]*rhs[2,1] + lhs[2,0]*rhs[2,2] + lhs[3,0]*rhs[2,3];
+    Result[0,3]:=lhs[0,0]*rhs[3,0] + lhs[1,0]*rhs[3,1] + lhs[2,0]*rhs[3,2] + lhs[3,0]*rhs[3,3];
+  
+    Result[1,0]:=lhs[0,1]*rhs[0,0] + lhs[1,1]*rhs[0,1] + lhs[2,1]*rhs[0,2] + lhs[3,1]*rhs[0,3];
+    Result[1,1]:=lhs[0,1]*rhs[1,0] + lhs[1,1]*rhs[1,1] + lhs[2,1]*rhs[1,2] + lhs[3,1]*rhs[1,3];
+    Result[1,2]:=lhs[0,1]*rhs[2,0] + lhs[1,1]*rhs[2,1] + lhs[2,1]*rhs[2,2] + lhs[3,1]*rhs[2,3];
+    Result[1,3]:=lhs[0,1]*rhs[3,0] + lhs[1,1]*rhs[3,1] + lhs[2,1]*rhs[3,2] + lhs[3,1]*rhs[3,3];
+
+    Result[2,0]:=lhs[0,2]*rhs[0,0] + lhs[1,2]*rhs[0,1] + lhs[2,2]*rhs[0,2] + lhs[3,2]*rhs[0,3];
+    Result[2,1]:=lhs[0,2]*rhs[1,0] + lhs[1,2]*rhs[1,1] + lhs[2,2]*rhs[1,2] + lhs[3,2]*rhs[1,3];
+    Result[2,2]:=lhs[0,2]*rhs[2,0] + lhs[1,2]*rhs[2,1] + lhs[2,2]*rhs[2,2] + lhs[3,2]*rhs[2,3];
+    Result[2,3]:=lhs[0,2]*rhs[3,0] + lhs[1,2]*rhs[3,1] + lhs[2,2]*rhs[3,2] + lhs[3,2]*rhs[3,3];
+
+    Result[3,0]:=lhs[0,3]*rhs[0,0] + lhs[1,3]*rhs[0,1] + lhs[2,3]*rhs[0,2] + lhs[3,3]*rhs[0,3];
+    Result[3,1]:=lhs[0,3]*rhs[1,0] + lhs[1,3]*rhs[1,1] + lhs[2,3]*rhs[1,2] + lhs[3,3]*rhs[1,3];
+    Result[3,2]:=lhs[0,3]*rhs[2,0] + lhs[1,3]*rhs[2,1] + lhs[2,3]*rhs[2,2] + lhs[3,3]*rhs[2,3];
+    Result[3,3]:=lhs[0,3]*rhs[3,0] + lhs[1,3]*rhs[3,1] + lhs[2,3]*rhs[3,2] + lhs[3,3]*rhs[3,3];
+}
+
+    {$IFNDEF PAS2C}
+    glPushMatrix;
+    glLoadMatrixf(@lhs[0, 0]);
+    glMultMatrixf(@rhs[0, 0]);
+    glGetFloatv(GL_MODELVIEW_MATRIX, @test[0, 0]);
+    glPopMatrix;
+
+    error:=false;
+    for i:=0 to 3 do
+      for j:=0 to 3 do
+        if Abs(test[i, j] - Result[i, j]) > 0.000001 then
+          error:=true;
+
+    if error then
+    begin
+        writeln('shall:');
+        for i:=0 to 3 do
+        begin
+          for j:=0 to 3 do
+            write(test[i, j]);
+          writeln;
+        end;
+
+        writeln('is:');
+        for i:=0 to 3 do
+        begin
+          for j:=0 to 3 do
+            write(Result[i, j]);
+          writeln;
+        end;
+        halt(0);
+    end;
+    {$ENDIF}
+
+end;
+
+
+end.
--- a/hedgewars/uMisc.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uMisc.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -48,7 +48,7 @@
          size: QWord;
          end;
 
-var conversionFormat: PSDL_PixelFormat;
+var conversionFormat : PSDL_PixelFormat;
 
 procedure movecursor(dx, dy: LongInt);
 var x, y: LongInt;
@@ -67,7 +67,7 @@
 var i: LongInt;
     png_ptr: ^png_struct;
     info_ptr: ^png_info;
-    f: file;
+    f: File;
     image: PScreenshot;
 begin
 image:= PScreenshot(screenshot);
@@ -140,6 +140,7 @@
     );
     image: PScreenshot;
     size: QWord;
+    writeResult:LongInt;
 begin
 image:= PScreenshot(screenshot);
 
@@ -167,8 +168,8 @@
 Rewrite(f, 1);
 if IOResult = 0 then
     begin
-    BlockWrite(f, head, sizeof(head));
-    BlockWrite(f, image^.buffer^, size);
+    BlockWrite(f, head, sizeof(head), writeResult);
+    BlockWrite(f, image^.buffer^, size, writeResult);
     Close(f);
     end
 else
@@ -270,6 +271,7 @@
 var convertedSurf: PSDL_Surface;
 begin
     doSurfaceConversion:= tmpsurf;
+{$IFNDEF WEBGL}
     if ((tmpsurf^.format^.bitsperpixel = 32) and (tmpsurf^.format^.rshift > tmpsurf^.format^.bshift)) or
        (tmpsurf^.format^.bitsperpixel = 24) then
     begin
@@ -277,6 +279,7 @@
         SDL_FreeSurface(tmpsurf);
         doSurfaceConversion:= convertedSurf;
     end;
+{$ENDIF}
 end;
 
 {$IFDEF SDL13}
@@ -309,4 +312,4 @@
     SDL_FreeFormat(conversionFormat);
 end;
 
-end.
+end.		
--- a/hedgewars/uPhysFSLayer.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uPhysFSLayer.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -38,12 +38,15 @@
 procedure physfsReaderSetBuffer(buf: pointer); cdecl; external PhyslayerLibName;
 procedure hedgewarsMountPackage(filename: PChar); cdecl; external PhyslayerLibName;
 
+{$IFNDEF PAS2C}
+//apparently pas2c doesn't render the functions below if it finds 'implementation' first
 implementation
 uses uUtils, uVariables, sysutils;
+{$ENDIF}
 
 function PHYSFS_init(argv0: PChar) : LongInt; cdecl; external PhysfsLibName;
 function PHYSFS_deinit() : LongInt; cdecl; external PhysfsLibName;
-function PHYSFSRWOPS_openRead(fname: PChar): PSDL_RWops; cdecl ; external PhyslayerLibName;
+function PHYSFSRWOPS_openRead(fname: PChar): PSDL_RWops; cdecl; external PhyslayerLibName;
 function PHYSFSRWOPS_openWrite(fname: PChar): PSDL_RWops; cdecl; external PhyslayerLibName;
 
 function PHYSFS_mount(newDir, mountPoint: PChar; appendToPath: LongBool) : LongInt; cdecl; external PhysfsLibName;
@@ -55,6 +58,13 @@
 
 procedure hedgewarsMountPackages(); cdecl; external PhyslayerLibName;
 
+{$IFDEF PAS2C}
+implementation
+uses uUtils, uVariables;
+{$ENDIF}
+
+(*****************************************************************)
+
 function rwopsOpenRead(fname: shortstring): PSDL_RWops;
 begin
     exit(PHYSFSRWOPS_openRead(Str2PChar(fname)));
@@ -117,7 +127,7 @@
             b[0]:= #0
             end
         end;
-        
+
 s:= s + b
 end;
 
--- a/hedgewars/uRandom.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uRandom.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -45,10 +45,11 @@
 procedure AddRandomness(r: LongWord); inline;
 begin
 n:= (n + 1) and $3F;
-cirbuf[n]:= cirbuf[n] xor r
+   cirbuf[n]:= cirbuf[n] xor r;
 end;
 
 function GetNext: Longword; inline;
+var s : string;
 begin
 n:= (n + 1) and $3F;
 cirbuf[n]:=
@@ -56,7 +57,8 @@
             cirbuf[(n +  9) and $3F])            {n - 55 mod 64}
             and $7FFFFFFF;                       {mod 2^31}
 
-GetNext:= cirbuf[n]
+   GetNext:= cirbuf[n];
+   str(GetNext, s);
 end;
 
 procedure SetRandomSeed(Seed: shortstring; dropAdditionalPart: boolean);
@@ -80,7 +82,7 @@
     cirbuf[i]:= $A98765 + 68; // odd number
 
 for i:= 0 to 1023 do
-    GetNext
+   GetNext;
 end;
 
 function GetRandomf: hwFloat;
@@ -90,7 +92,7 @@
 GetRandomf.QWordValue:= GetNext
 end;
 
-function GetRandom(m: LongWord): LongWord; inline;
+function GetRandom(m: LongWord): LongWord; overload; inline;
 begin
 GetNext;
 GetRandom:= GetNext mod m
--- a/hedgewars/uRender.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uRender.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -17,12 +17,13 @@
  *)
 
 {$INCLUDE "options.inc"}
+{$IF GLunit = GL}{$DEFINE GLunit:=GL,GLext}{$ENDIF}
 
 unit uRender;
 
 interface
 
-uses SDLh, uTypes, GLunit, uConsts;
+uses SDLh, uTypes, GLunit, uConsts, uStore, uMatrix;
 
 procedure DrawSprite            (Sprite: TSprite; X, Y, Frame: LongInt);
 procedure DrawSprite            (Sprite: TSprite; X, Y, FrameX, FrameY: LongInt);
@@ -52,7 +53,6 @@
 procedure Tint                  (r, g, b, a: Byte); inline;
 procedure Tint                  (c: Longword); inline;
 
-
 implementation
 uses uVariables;
 
@@ -75,6 +75,7 @@
 begin
 DrawTextureFromRectDir(X, Y, r^.w, r^.h, r, SourceTexture, 1)
 end;
+
 procedure DrawTextureFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture); inline;
 begin
 DrawTextureFromRectDir(X, Y, W, H, r, SourceTexture, 1)
@@ -140,6 +141,63 @@
 
 glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
 glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]);
+glDrawArrays(GL_TRIANGLE_FAN, 0, High(VertexBuffer) - Low(VertexBuffer) + 1);
+end;
+
+
+procedure DrawTextureFromRectDir(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture);
+var
+    rr: TSDL_Rect;
+    VertexBuffer, TextureBuffer: array [0..3] of TVertex2f;
+    //VertexBuffer, TextureBuffer: TVertexRect;
+    _l, _r, _t, _b: GLfloat;
+begin
+if (SourceTexture^.h = 0) or (SourceTexture^.w = 0) then
+    exit;
+
+// do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
+if (abs(X) > W) and ((abs(X + W / 2) - W / 2) > cScreenWidth / cScaleFactor) then
+    exit;
+if (abs(Y) > H) and ((abs(Y + H / 2 - (0.5 * cScreenHeight)) - H / 2) > cScreenHeight / cScaleFactor) then
+    exit;
+
+rr.x:= X;
+rr.y:= Y;
+rr.w:= W;
+rr.h:= H;
+
+_l:= r^.x / SourceTexture^.w * SourceTexture^.rx;
+_r:= (r^.x + r^.w) / SourceTexture^.w * SourceTexture^.rx;
+_t:= r^.y / SourceTexture^.h * SourceTexture^.ry;
+_b:= (r^.y + r^.h) / SourceTexture^.h * SourceTexture^.ry;
+
+glBindTexture(GL_TEXTURE_2D, SourceTexture^.id);
+
+VertexBuffer[0].X:= X;
+VertexBuffer[0].Y:= Y;
+VertexBuffer[1].X:= rr.w + X;
+VertexBuffer[1].Y:= Y;
+VertexBuffer[2].X:= rr.w + X;
+VertexBuffer[2].Y:= rr.h + Y;
+VertexBuffer[3].X:= X;
+VertexBuffer[3].Y:= rr.h + Y;
+
+TextureBuffer[0].X:= _l;
+TextureBuffer[0].Y:= _t;
+TextureBuffer[1].X:= _r;
+TextureBuffer[1].Y:= _t;
+TextureBuffer[2].X:= _r;
+TextureBuffer[2].Y:= _b;
+TextureBuffer[3].X:= _l;
+TextureBuffer[3].Y:= _b;
+
+SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer));
+SetTexCoordPointer(@TextureBuffer[0], Length(VertexBuffer));
+
+{$IFDEF GL2}
+UpdateModelviewProjection;
+{$ENDIF}
+
 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
 end;
 
@@ -151,17 +209,30 @@
 procedure DrawTexture(X, Y: LongInt; Texture: PTexture; Scale: GLfloat);
 begin
 
+{$IFDEF GL2}
+hglPushMatrix;
+hglTranslatef(X, Y, 0);
+hglScalef(Scale, Scale, 1);
+{$ELSE}
 glPushMatrix;
 glTranslatef(X, Y, 0);
 glScalef(Scale, Scale, 1);
+{$ENDIF}
 
 glBindTexture(GL_TEXTURE_2D, Texture^.id);
 
-glVertexPointer(2, GL_FLOAT, 0, @Texture^.vb);
-glTexCoordPointer(2, GL_FLOAT, 0, @Texture^.tb);
+SetVertexPointer(@Texture^.vb, Length(Texture^.vb));
+SetTexCoordPointer(@Texture^.tb, Length(Texture^.vb));
+
+{$IFDEF GL2}
+UpdateModelviewProjection;
 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(Texture^.vb));
+hglPopMatrix;
+{$ELSE}
+glDrawArrays(GL_TRIANGLE_FAN, 0, Length(Texture^.vb));
+glPopMatrix;
+{$ENDIF}
 
-glPopMatrix
 end;
 
 procedure DrawTextureF(Texture: PTexture; Scale: GLfloat; X, Y, Frame, Dir, w, h: LongInt);
@@ -180,14 +251,25 @@
 if (abs(Y) > H) and ((abs(Y + OffsetY - (0.5 * cScreenHeight)) - W / 2) * cScaleFactor > cScreenHeight) then
     exit;
 
+{$IFDEF GL2}
+hglPushMatrix;
+hglTranslatef(X, Y, 0);
+{$ELSE}
 glPushMatrix;
 glTranslatef(X, Y, 0);
+{$ENDIF}
+
 if Dir = 0 then Dir:= 1;
 
+{$IFDEF GL2}
+hglRotatef(Angle, 0, 0, Dir);
+hglTranslatef(Dir*OffsetX, OffsetY, 0);
+hglScalef(Scale, Scale, 1);
+{$ELSE}
 glRotatef(Angle, 0, 0, Dir);
-
 glTranslatef(Dir*OffsetX, OffsetY, 0);
 glScalef(Scale, Scale, 1);
+{$ENDIF}
 
 // Any reason for this call? And why only in t direction, not s?
 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
@@ -222,11 +304,21 @@
 TextureBuffer[3].X:= fl;
 TextureBuffer[3].Y:= fb;
 
-glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
-glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]);
+SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer));
+SetTexCoordPointer(@TextureBuffer[0], Length(VertexBuffer));
+
+{$IFDEF GL2}
+UpdateModelviewProjection;
+{$ENDIF}
+
 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
 
-glPopMatrix
+{$IFDEF GL2}
+hglPopMatrix;
+{$ELSE}
+glPopMatrix;
+{$ENDIF}
+
 end;
 
 procedure DrawSpriteRotated(Sprite: TSprite; X, Y, Dir: LongInt; Angle: real);
@@ -239,19 +331,42 @@
 
 procedure DrawSpriteRotatedF(Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real);
 begin
+
+{$IFDEF GL2}
+hglPushMatrix;
+hglTranslatef(X, Y, 0);
+{$ELSE}
 glPushMatrix;
 glTranslatef(X, Y, 0);
+{$ENDIF}
 
 if Dir < 0 then
+{$IFDEF GL2}
+    hglRotatef(Angle, 0, 0, -1)
+{$ELSE}
     glRotatef(Angle, 0, 0, -1)
+{$ENDIF}
 else
+{$IFDEF GL2}
+    hglRotatef(Angle, 0, 0,  1);
+{$ELSE}
     glRotatef(Angle, 0, 0,  1);
+{$ENDIF}
 if Dir < 0 then
+{$IFDEF GL2}
+    hglScalef(-1.0, 1.0, 1.0);
+{$ELSE}
     glScalef(-1.0, 1.0, 1.0);
+{$ENDIF}
 
 DrawSprite(Sprite, -SpritesData[Sprite].Width div 2, -SpritesData[Sprite].Height div 2, Frame);
 
-glPopMatrix
+{$IFDEF GL2}
+hglPopMatrix;
+{$ELSE}
+glPopMatrix;
+{$ENDIF}
+
 end;
 
 procedure DrawTextureRotated(Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real);
@@ -263,17 +378,29 @@
 if (abs(Y) > 2 * hh) and ((abs(Y - 0.5 * cScreenHeight) - hh) > cScreenHeight / cScaleFactor) then
     exit;
 
+{$IFDEF GL2}
+hglPushMatrix;
+hglTranslatef(X, Y, 0);
+{$ELSE}
 glPushMatrix;
 glTranslatef(X, Y, 0);
+{$ENDIF}
 
 if Dir < 0 then
     begin
     hw:= - hw;
+{$IFDEF GL2}
+    hglRotatef(Angle, 0, 0, -1);
+{$ELSE}
     glRotatef(Angle, 0, 0, -1);
+{$ENDIF}
     end
 else
-    glRotatef(Angle, 0, 0,  1);
-
+{$IFDEF GL2}
+    hglRotatef(Angle, 0, 0,  1);
+{$ELSE}
+    glRotatef(Angle, 0, 0, 1);
+{$ENDIF}
 
 glBindTexture(GL_TEXTURE_2D, Texture^.id);
 
@@ -286,11 +413,21 @@
 VertexBuffer[3].X:= -hw;
 VertexBuffer[3].Y:= hh;
 
-glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
-glTexCoordPointer(2, GL_FLOAT, 0, @Texture^.tb);
+SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer));
+SetTexCoordPointer(@Texture^.tb, Length(VertexBuffer));
+
+{$IFDEF GL2}
+UpdateModelviewProjection;
+{$ENDIF}
+
 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
 
-glPopMatrix
+{$IFDEF GL2}
+hglPopMatrix;
+{$ELSE}
+glPopMatrix;
+{$ENDIF}
+
 end;
 
 procedure DrawSprite(Sprite: TSprite; X, Y, Frame: LongInt);
@@ -351,8 +488,9 @@
 procedure DrawLine(X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte);
 var VertexBuffer: array [0..1] of TVertex2f;
 begin
+    glEnable(GL_LINE_SMOOTH);
+{$IFNDEF GL2}
     glDisable(GL_TEXTURE_2D);
-    glEnable(GL_LINE_SMOOTH);
 
     glPushMatrix;
     glTranslatef(WorldDx, WorldDy, 0);
@@ -364,13 +502,37 @@
     VertexBuffer[1].X:= X1;
     VertexBuffer[1].Y:= Y1;
 
-    glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
+    SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer));
     glDrawArrays(GL_LINES, 0, Length(VertexBuffer));
     Tint($FF, $FF, $FF, $FF);
-    
+
     glPopMatrix;
-    
+
     glEnable(GL_TEXTURE_2D);
+
+{$ELSE}
+    EnableTexture(False);
+
+    hglPushMatrix;
+    hglTranslatef(WorldDx, WorldDy, 0);
+    glLineWidth(Width);
+
+    UpdateModelviewProjection;
+
+    Tint(r, g, b, a);
+    VertexBuffer[0].X:= X0;
+    VertexBuffer[0].Y:= Y0;
+    VertexBuffer[1].X:= X1;
+    VertexBuffer[1].Y:= Y1;
+
+    SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer));
+    glDrawArrays(GL_LINES, 0, Length(VertexBuffer));
+    Tint($FF, $FF, $FF, $FF);
+
+    hglPopMatrix;
+    EnableTexture(True);
+
+{$ENDIF}
     glDisable(GL_LINE_SMOOTH);
 end;
 
@@ -378,12 +540,17 @@
 var VertexBuffer: array [0..3] of TVertex2f;
 begin
 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
+
 if (abs(r.x) > r.w) and ((abs(r.x + r.w / 2) - r.w / 2) * cScaleFactor > cScreenWidth) then
     exit;
 if (abs(r.y) > r.h) and ((abs(r.y + r.h / 2 - (0.5 * cScreenHeight)) - r.h / 2) * cScaleFactor > cScreenHeight) then
     exit;
 
+{$IFDEF GL2}
+EnableTexture(False);
+{$ELSE}
 glDisable(GL_TEXTURE_2D);
+{$ENDIF}
 
 Tint($00, $00, $00, $80);
 
@@ -396,21 +563,27 @@
 VertexBuffer[3].X:= r.x;
 VertexBuffer[3].Y:= r.y + r.h;
 
-glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
+SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer));
 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
 
 Tint($FF, $FF, $FF, $FF);
+
+{$IFDEF GL2}
+EnableTexture(True);
+{$ELSE}
 glEnable(GL_TEXTURE_2D)
+{$ENDIF}
+
 end;
 
-procedure DrawCircle(X, Y, Radius, Width: LongInt; r, g, b, a: Byte); 
+procedure DrawCircle(X, Y, Radius, Width: LongInt; r, g, b, a: Byte);
 begin
     Tint(r, g, b, a);
-    DrawCircle(X, Y, Radius, Width); 
+    DrawCircle(X, Y, Radius, Width);
     Tint($FF, $FF, $FF, $FF);
 end;
 
-procedure DrawCircle(X, Y, Radius, Width: LongInt); 
+procedure DrawCircle(X, Y, Radius, Width: LongInt);
 var
     i: LongInt;
     CircleVertex: array [0..59] of TVertex2f;
@@ -419,6 +592,9 @@
         CircleVertex[i].X := X + Radius*cos(i*pi/30);
         CircleVertex[i].Y := Y + Radius*sin(i*pi/30);
     end;
+
+{$IFNDEF GL2}
+
     glDisable(GL_TEXTURE_2D);
     glEnable(GL_LINE_SMOOTH);
     glPushMatrix;
@@ -428,6 +604,18 @@
     glPopMatrix;
     glEnable(GL_TEXTURE_2D);
     glDisable(GL_LINE_SMOOTH);
+
+{$ELSE}
+    EnableTexture(False);
+    glEnable(GL_LINE_SMOOTH);
+    hglPushMatrix;
+    glLineWidth(Width);
+    SetVertexPointer(@CircleVertex[0], 60);
+    glDrawArrays(GL_LINE_LOOP, 0, 60);
+    hglPopMatrix;
+    EnableTexture(True);
+    glDisable(GL_LINE_SMOOTH);
+{$ENDIF}
 end;
 
 
@@ -460,10 +648,15 @@
         r:= (Step + 1) * 32 / HHTexture^.w
     end;
 
-
+{$IFDEF GL2}
+    hglPushMatrix();
+    hglTranslatef(X, Y, 0);
+    hglRotatef(Angle, 0, 0, 1);
+{$ELSE}
     glPushMatrix();
     glTranslatef(X, Y, 0);
     glRotatef(Angle, 0, 0, 1);
+{$ENDIF}
 
     glBindTexture(GL_TEXTURE_2D, HHTexture^.id);
 
@@ -476,11 +669,20 @@
     TextureBuffer[3].X:= l;
     TextureBuffer[3].Y:= b;
 
-    glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
-    glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]);
+    SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer));
+    SetTexCoordPointer(@TextureBuffer[0], Length(VertexBuffer));
+
+{$IFDEF GL2}
+    UpdateModelviewProjection;
+{$ENDIF}
+
     glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
 
-    glPopMatrix
+{$IFDEF GL2}
+    hglPopMatrix;
+{$ELSE}
+    glPopMatrix;
+{$ENDIF}
 end;
 
 procedure DrawScreenWidget(widget: POnScreenWidget);
@@ -494,9 +696,9 @@
         if RealTicks > (fadeAnimStart + FADE_ANIM_TIME) then
             fadeAnimStart:= 0
         else
-            if show then 
+            if show then
                 alpha:= Byte(trunc((RealTicks - fadeAnimStart)/FADE_ANIM_TIME * $FF))
-            else 
+            else
                 alpha:= Byte($FF - trunc((RealTicks - fadeAnimStart)/FADE_ANIM_TIME * $FF));
         end;
 
@@ -526,12 +728,14 @@
     end;
 {$ELSE}
 begin
-widget:= widget; // avoid hint
+{widget:= widget; // avoid hint}
 {$ENDIF}
 end;
 
 procedure Tint(r, g, b, a: Byte); inline;
-var nc, tw: Longword;
+var
+    nc, tw: Longword;
+    scale:Real = 1.0/255.0;
 begin
     nc:= (a shl 24) or (b shl 16) or (g shl 8) or r;
 
@@ -548,7 +752,12 @@
         b:= tw
         end;
 
+    {$IFDEF GL2}
+    glUniform4f(uMainTintLocation, r*scale, g*scale, b*scale, a*scale);
+    //glColor4ub(r, g, b, a);
+    {$ELSE}
     glColor4ub(r, g, b, a);
+    {$ENDIF}
     lastTint:= nc;
 end;
 
@@ -557,4 +766,5 @@
     Tint(((c shr 24) and $FF), ((c shr 16) and $FF), (c shr 8) and $FF, (c and $FF))
 end;
 
+
 end.
--- a/hedgewars/uRenderUtils.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uRenderUtils.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -68,7 +68,7 @@
     r.y:= rect^.y + 2;
     r.w:= rect^.w - 2;
     r.h:= rect^.h - 4;
-    SDL_FillRect(Surface, @r, FillColor)
+    SDL_FillRect(Surface, @r, FillColor);
 end;
 (*
 function WriteInRoundRect(Surface: PSDL_Surface; X, Y: LongInt; Color: LongWord; Font: THWFont; s: ansistring): TSDL_Rect;
@@ -115,6 +115,7 @@
     pixels: PLongWordArray;
 begin
     TryDo(Surface^.format^.BytesPerPixel = 4, 'flipSurface failed, expecting 32 bit surface', true);
+    SDL_LockSurface(Surface);
     pixels:= Surface^.pixels;
     if Vertical then
     for y := 0 to (Surface^.h div 2) - 1 do
@@ -136,6 +137,7 @@
             pixels^[i]:= pixels^[j];
             pixels^[j]:= tmpPixel;
             end;
+    SDL_UnlockSurface(Surface);
 end;
 
 procedure copyToXY(src, dest: PSDL_Surface; destX, destY: LongInt); inline;
@@ -150,6 +152,10 @@
 begin
     maxDest:= (dest^.pitch div 4) * dest^.h;
     maxSrc:= (src^.pitch div 4) * src^.h;
+
+    SDL_LockSurface(src);
+    SDL_LockSurface(dest);
+
     srcPixels:= src^.pixels;
     destPixels:= dest^.pixels;
 
@@ -169,6 +175,9 @@
             destPixels^[i]:= SDL_MapRGBA(dest^.format, r0, g0, b0, a0);
             end;
         end;
+
+    SDL_UnlockSurface(src);
+    SDL_UnlockSurface(dest);
 end;
 
 procedure DrawSprite2Surf(sprite: TSprite; dest: PSDL_Surface; x,y: LongInt); inline;
@@ -199,6 +208,9 @@
 begin
     //max:= (dest^.pitch div 4) * dest^.h;
     yMax:= dest^.pitch div 4;
+
+    SDL_LockSurface(dest);
+
     destPixels:= dest^.pixels;
 
     dx:= abs(x1-x0);
@@ -225,7 +237,8 @@
             err:= err + dx;
             y0:=y0+sy
             end;
-        end; 
+        end;
+    SDL_UnlockSurface(dest);
 end;
 
 procedure copyRotatedSurface(src, dest: PSDL_Surface); // this is necessary since width/height are read only in SDL, apparently
@@ -235,6 +248,9 @@
     TryDo(src^.format^.BytesPerPixel = 4, 'rotateSurface failed, expecting 32 bit surface', true);
     TryDo(dest^.format^.BytesPerPixel = 4, 'rotateSurface failed, expecting 32 bit surface', true);
 
+    SDL_LockSurface(src);
+    SDL_LockSurface(dest);
+
     srcPixels:= src^.pixels;
     destPixels:= dest^.pixels;
 
@@ -246,6 +262,10 @@
             destPixels^[j]:= srcPixels^[i];
             inc(j)
             end;
+
+    SDL_UnlockSurface(src);
+    SDL_UnlockSurface(dest);
+
 end;
 
 function RenderStringTex(s: ansistring; Color: Longword; font: THWFont): PTexture;
@@ -282,11 +302,11 @@
 var textWidth, textHeight, x, y, w, h, i, j, pos, prevpos, line, numLines, edgeWidth, edgeHeight, cornerWidth, cornerHeight: LongInt;
     finalSurface, tmpsurf, rotatedEdge: PSDL_Surface;
     rect: TSDL_Rect;
-    chars: set of char = [#9,' ',';',':','?','!',','];
+    //chars: set of char = [#9,' ',';',':','?','!',','];
     substr: shortstring;
     edge, corner, tail: TSPrite;
 begin
-    case SpeechType of
+      case SpeechType of
         1: begin;
         edge:= sprSpeechEdge;
         corner:= sprSpeechCorner;
@@ -326,7 +346,7 @@
         begin
         w:= 0;
         i:= round(Sqrt(length(s)) * 2);
-        s:= WrapText(s, #1, chars, i);
+       // s:= WrapText(s, #1, chars, i);
         pos:= 1; prevpos:= 0; line:= 0;
     // Find the longest line for the purposes of centring the text.  Font dependant.
         while pos <= length(s) do
@@ -463,6 +483,7 @@
 
     SDL_FreeSurface(rotatedEdge);
     SDL_FreeSurface(finalSurface);
+
 end;
 
 end.
--- a/hedgewars/uScript.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uScript.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -81,7 +81,7 @@
     uTextures,
     uLandGraphics,
     SDLh,
-    SysUtils, 
+    SysUtils,
     uIO,
     uPhysFSLayer
     ;
@@ -112,7 +112,7 @@
 
 function lc_band(L: PLua_State): LongInt; Cdecl;
 begin
-    if lua_gettop(L) <> 2 then 
+    if lua_gettop(L) <> 2 then
         begin
         LuaError('Lua: Wrong number of parameters passed to band!');
         lua_pushnil(L);
@@ -124,7 +124,7 @@
 
 function lc_bor(L: PLua_State): LongInt; Cdecl;
 begin
-    if lua_gettop(L) <> 2 then 
+    if lua_gettop(L) <> 2 then
         begin
         LuaError('Lua: Wrong number of parameters passed to bor!');
         lua_pushnil(L);
@@ -136,19 +136,19 @@
 
 function lc_bnot(L: PLua_State): LongInt; Cdecl;
 begin
-    if lua_gettop(L) <> 1 then 
+    if lua_gettop(L) <> 1 then
         begin
         LuaError('Lua: Wrong number of parameters passed to bnot!');
         lua_pushnil(L);
         end
     else
-        lua_pushinteger(L, not lua_tointeger(L, 1));
+        lua_pushinteger(L, (not lua_tointeger(L, 1)));
     lc_bnot := 1;
 end;
 
 function lc_div(L: PLua_State): LongInt; Cdecl;
 begin
-    if lua_gettop(L) <> 2 then 
+    if lua_gettop(L) <> 2 then
         begin
         LuaError('Lua: Wrong number of parameters passed to div!');
         lua_pushnil(L);
@@ -303,7 +303,7 @@
         HealthCrate, lua_toboolean(L, 3), lua_toboolean(L, 4));
         lua_pushinteger(L, gear^.uid);
         end;
-    lc_spawnfakehealthcrate := 1;        
+    lc_spawnfakehealthcrate := 1;
 end;
 
 function lc_spawnfakeammocrate(L: PLua_State): LongInt; Cdecl;
@@ -332,7 +332,7 @@
         lua_pushnil(L);
         end
     else
-        begin  
+        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);
@@ -361,7 +361,7 @@
         else
             lua_pushnil(L);
         end;
-    lc_spawnhealthcrate := 1;        
+    lc_spawnhealthcrate := 1;
 end;
 
 function lc_spawnammocrate(L: PLua_State): LongInt; Cdecl;
@@ -374,7 +374,7 @@
         end
     else
         begin
-        if (lua_gettop(L) = 3) then 
+        if (lua_gettop(L) = 3) then
              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
@@ -470,7 +470,7 @@
         c:= lua_toboolean(L, 5);
 
         vg:= AddVisualGear(x, y, vgt, s, c);
-        if vg <> nil then 
+        if vg <> nil then
             begin
             lastVisualGearByUID:= vg;
             lua_pushinteger(L, vg^.uid)
@@ -794,7 +794,7 @@
             for j:= 0 to 7 do
                 begin
                 hh:= team^.Hedgehogs[j];
-                if (hh.Gear <> nil) or (hh.GearHidden <> nil) then 
+                if (hh.Gear <> nil) or (hh.GearHidden <> nil) then
                     begin
                     FreeTexture(hh.NameTagTex);
                     hh.NameTagTex:= RenderStringTex(hh.Name, clan^.Color, fnt16);
@@ -1053,7 +1053,7 @@
                 prevgear^.Z := cHHZ;
                 prevgear^.Message:= prevgear^.Message or gmRemoveFromList or gmAddToList;
                 end;
-            
+
             SwitchCurrentHedgehog(gear^.Hedgehog);
             CurrentTeam:= CurrentHedgehog^.Team;
 
@@ -1076,7 +1076,7 @@
         if (gear <> nil) and (gear^.Hedgehog <> nil) then
             AddAmmoAmount(gear^.Hedgehog^, TAmmoType(lua_tointeger(L, 2)), lua_tointeger(L,3) );
     end else
-    
+
     if lua_gettop(L) = 2 then
     begin
     gear:= GearByUID(lua_tointeger(L, 1));
@@ -1114,7 +1114,7 @@
     if (lua_gettop(L) = 2) then
         begin
         gear:= GearByUID(lua_tointeger(L, 1));
-        if (gear <> nil) and (gear^.Hedgehog <> nil) then 
+        if (gear <> nil) and (gear^.Hedgehog <> nil) then
             begin
             ammo:= GetAmmoEntry(gear^.Hedgehog^, TAmmoType(lua_tointeger(L, 2)));
             if ammo^.AmmoType = amNothing then
@@ -1124,7 +1124,7 @@
             end
         else lua_pushinteger(L, 0)
         end
-    else 
+    else
         begin
         LuaError('Lua: Wrong number of parameters passed to GetAmmoCount!');
         lua_pushnil(L)
@@ -1147,7 +1147,7 @@
             gear^.Health:= lua_tointeger(L, 2);
 
         if (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
-            begin  
+            begin
             RenderHealth(gear^.Hedgehog^);
             RecountTeamHealth(gear^.Hedgehog^.Team)
             end;
@@ -1969,7 +1969,7 @@
             if StoreCnt-1 < k then AddAmmoStore;
             inc(k)
             end
-else 
+else
     for i:= 0 to Pred(TeamsCount) do
         begin
         for j:= 0 to Pred(TeamsArray[i]^.HedgehogsNumber) do
@@ -2021,7 +2021,7 @@
     exit;
 
 f:= pfsOpenRead(s);
-if f = nil then 
+if f = nil then
     exit;
 
 physfsReaderSetBuffer(@buf);
@@ -2070,7 +2070,7 @@
 
 procedure ScriptCall(fname : shortstring);
 begin
-if not ScriptLoaded or (not ScriptExists(fname)) then
+if (not ScriptLoaded) or (not ScriptExists(fname)) then
     exit;
 SetGlobals;
 lua_getglobal(luaState, Str2PChar(fname));
@@ -2121,7 +2121,7 @@
 
 function ScriptCall(fname : shortstring; par1, par2, par3, par4 : LongInt) : LongInt;
 begin
-if not ScriptLoaded or (not ScriptExists(fname)) then
+if (not ScriptLoaded) or (not ScriptExists(fname)) then
     exit;
 SetGlobals;
 lua_getglobal(luaState, Str2PChar(fname));
@@ -2218,7 +2218,7 @@
             AddAmmoStore;
             TeamsArray[i]^.Hedgehogs[j].AmmoStore:= StoreCnt - 1
             end
-else 
+else
     for i:= 0 to Pred(TeamsCount) do
         begin
         if ScriptExists('onNewAmmoStore') then
--- a/hedgewars/uSound.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uSound.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -315,7 +315,7 @@
     WriteLnToConsole(msgOK);
 
     Mix_AllocateChannels(Succ(chanTPU));
-    ChangeVolume(cInitVolume);	
+    ChangeVolume(cInitVolume);
 end;
 
 procedure ResetSound;
@@ -452,7 +452,7 @@
     i:= 0;
     while (i<High(VoiceList)) and (VoiceList[i].snd = sndNone) do
         inc(i);
-    
+
     if (VoiceList[i].snd <> sndNone) then
         begin
         LastVoice.snd:= VoiceList[i].snd;
--- a/hedgewars/uStore.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uStore.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -21,7 +21,7 @@
 
 unit uStore;
 interface
-uses StrUtils, SysUtils, uConsts, SDLh, GLunit, uTypes, uLandTexture, uCaptions, uChat;
+uses {$IFNDEF PAS2C} StrUtils, {$ENDIF}SysUtils, uConsts, SDLh, GLunit, uTypes, uLandTexture, uCaptions, uChat;
 
 procedure initModule;
 procedure freeModule;
@@ -55,6 +55,17 @@
 procedure WarpMouse(x, y: Word); inline;
 procedure SwapBuffers; {$IFDEF USE_VIDEO_RECORDING}cdecl{$ELSE}inline{$ENDIF};
 
+{$IFDEF GL2}
+procedure UpdateModelviewProjection;
+procedure EnableTexture(enable:Boolean);
+{$ENDIF}
+
+procedure SetTexCoordPointer(p: Pointer;n: Integer);
+procedure SetVertexPointer(p: Pointer;n: Integer);
+procedure SetColorPointer(p: Pointer;n: Integer);
+procedure BeginWater;
+procedure EndWater;
+
 implementation
 uses uMisc, uConsole, uVariables, uUtils, uTextures, uRender, uRenderUtils, uCommands
     , uPhysFSLayer
@@ -75,7 +86,18 @@
     numsquares : LongInt;
     ProgrTex: PTexture;
 
-const 
+{$IFDEF GL2}
+    shaderMain: GLuint;
+    shaderWater: GLuint;
+
+    // attributes
+{$ENDIF}
+
+{$IFDEF WEBGL}
+    OpenGLSetupedBefore : boolean;
+{$ENDIF}
+
+const
     cHHFileName = 'Hedgehog';
     cCHFileName = 'Crosshair';
 
@@ -201,7 +223,7 @@
                     foundBot:= true;
                     // initially was going to do the highest botlevel of the team, but for now, just apply if entire team has same bot level
                     if maxLevel = -1 then maxLevel:= BotLevel
-                    else if (maxLevel > 0) and (maxLevel <> BotLevel) then maxLevel:= 0; 
+                    else if (maxLevel > 0) and (maxLevel <> BotLevel) then maxLevel:= 0;
                     //if (maxLevel > 0) and (BotLevel < maxLevel) then maxLevel:= BotLevel
                     end
                 else if Gear <> nil then  maxLevel:= 0;
@@ -209,7 +231,7 @@
         if foundBot then
             begin
             // disabled the plain flag - I think it looks ok even w/ full bars obscuring CPU
-            //if (maxLevel > 0) and (maxLevel < 3) then Flag:= 'cpu_plain' else 
+            //if (maxLevel > 0) and (maxLevel < 3) then Flag:= 'cpu_plain' else
             Flag:= 'cpu'
             end
         else if (Flag = 'cpu') or (Flag = 'cpu_plain') then
@@ -219,10 +241,10 @@
         TryDo(flagsurf <> nil, 'Failed to load flag "' + Flag + '" as well as the default flag', true);
 
         case maxLevel of
-            1: copyToXY(SpritesData[sprBotlevels].Surface, flagsurf, 0, 0); 
-            2: copyToXYFromRect(SpritesData[sprBotlevels].Surface, flagsurf, 5, 2, 17, 13, 5, 2); 
-            3: copyToXYFromRect(SpritesData[sprBotlevels].Surface, flagsurf, 9, 5, 13, 10, 9, 5); 
-            4: copyToXYFromRect(SpritesData[sprBotlevels].Surface, flagsurf, 13, 9, 9, 6, 13, 9); 
+            1: copyToXY(SpritesData[sprBotlevels].Surface, flagsurf, 0, 0);
+            2: copyToXYFromRect(SpritesData[sprBotlevels].Surface, flagsurf, 5, 2, 17, 13, 5, 2);
+            3: copyToXYFromRect(SpritesData[sprBotlevels].Surface, flagsurf, 9, 5, 13, 10, 9, 5);
+            4: copyToXYFromRect(SpritesData[sprBotlevels].Surface, flagsurf, 13, 9, 9, 6, 13, 9);
             5: copyToXYFromRect(SpritesData[sprBotlevels].Surface, flagsurf, 17, 11, 5, 4, 17, 11)
             end;
 
@@ -313,7 +335,7 @@
     i, imflags: LongInt;
 begin
 AddFileLog('StoreLoad()');
-
+WriteLnToConsole('Entering StoreLoad');
 if not reload then
     for fi:= Low(THWFont) to High(THWFont) do
         with Fontz[fi] do
@@ -384,7 +406,7 @@
                 if not reload then
                     begin
 {$IFDEF USE_CONTEXT_RESTORE}
-                    Surface:= tmpsurf 
+                    Surface:= tmpsurf
 {$ELSE}
                     if saveSurf then
                         Surface:= tmpsurf
@@ -442,8 +464,11 @@
 if not reload then
     AddProgress;
 IMG_Quit();
+
+WriteLnToConsole('Leaving StoreLoad');
 end;
 
+{$IFNDEF PAS2C}
 {$IF DEFINED(USE_S3D_RENDERING) OR DEFINED(USE_VIDEO_RECORDING)}
 procedure CreateFramebuffer(var frame, depth, tex: GLuint);
 begin
@@ -468,6 +493,7 @@
     glDeleteFramebuffersEXT(1, @frame);
 end;
 {$ENDIF}
+{$ENDIF}
 
 procedure StoreRelease(reload: boolean);
 var ii: TSprite;
@@ -542,6 +568,7 @@
                 end;
             end;
         end;
+{$IFNDEF PAS2C}
 {$IFDEF USE_VIDEO_RECORDING}
     if defaultFrame <> 0 then
         DeleteFramebuffer(defaultFrame, depthv, texv);
@@ -553,6 +580,7 @@
         DeleteFramebuffer(framer, depthr, texr);
         end
 {$ENDIF}
+{$ENDIF}
 end;
 
 
@@ -666,6 +694,8 @@
 
 function glLoadExtension(extension : shortstring) : boolean;
 begin
+//TODO: pas2c doesn't 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
@@ -678,6 +708,7 @@
     else
         AddFileLog('OpenGL - "' + extension + '" failed to load');
 {$ENDIF}
+{$ENDIF}
 end;
 
 procedure SetupOpenGLAttributes;
@@ -700,12 +731,117 @@
     SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); // try to prefer hardware rendering
 end;
 
+{$IFDEF GL2}
+function CompileShader(shaderFile: string; shaderType: GLenum): GLuint;
+var
+    shader: GLuint;
+    f: Textfile;
+    source, line: AnsiString;
+    sourceA: Pchar;
+    lengthA: GLint;
+    compileResult: GLint;
+    logLength: GLint;
+    log: PChar;
+begin
+    Assign(f, PathPrefix + cPathz[ptShaders] + '/' + shaderFile);
+    filemode:= 0; // readonly
+    Reset(f);
+    if IOResult <> 0 then
+    begin
+        AddFileLog('Unable to load ' + shaderFile);
+        halt(-1);
+    end;
+
+    source:='';
+    while not eof(f) do
+    begin
+        ReadLn(f, line);
+        source:= source + line + #10;
+    end;
+
+    Close(f);
+
+    WriteLnToConsole('Compiling shader: ' + PathPrefix + cPathz[ptShaders] + '/' + shaderFile);
+
+    sourceA:=PChar(source);
+    lengthA:=Length(source);
+
+    shader:=glCreateShader(shaderType);
+    glShaderSource(shader, 1, @sourceA, @lengthA);
+    glCompileShader(shader);
+    glGetShaderiv(shader, GL_COMPILE_STATUS, @compileResult);
+    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, @logLength);
+
+    if logLength > 1 then
+    begin
+        log := GetMem(logLength);
+        glGetShaderInfoLog(shader, logLength, nil, log);
+        WriteLnToConsole('========== Compiler log  ==========');
+        WriteLnToConsole(shortstring(log));
+        WriteLnToConsole('===================================');
+        FreeMem(log, logLength);
+    end;
+
+    if compileResult <> GL_TRUE then
+    begin
+        WriteLnToConsole('Shader compilation failed, halting');
+        halt(-1);
+    end;
+
+    CompileShader:= shader;
+end;
+
+function CompileProgram(shaderName: string): GLuint;
+var
+    program_: GLuint;
+    vs, fs: GLuint;
+    linkResult: GLint;
+    logLength: GLint;
+    log: PChar;
+begin
+    program_:= glCreateProgram();
+    vs:= CompileShader(shaderName + '.vs', GL_VERTEX_SHADER);
+    fs:= CompileShader(shaderName + '.fs', GL_FRAGMENT_SHADER);
+    glAttachShader(program_, vs);
+    glAttachShader(program_, fs);
+
+    glBindAttribLocation(program_, aVertex, PChar('vertex'));
+    glBindAttribLocation(program_, aTexCoord, PChar('texcoord'));
+    glBindAttribLocation(program_, aColor, PChar('color'));
+
+    glLinkProgram(program_);
+    glDeleteShader(vs);
+    glDeleteShader(fs);
+
+    glGetProgramiv(program_, GL_LINK_STATUS, @linkResult);
+    glGetProgramiv(program_, GL_INFO_LOG_LENGTH, @logLength);
+
+    if logLength > 1 then
+    begin
+        log := GetMem(logLength);
+        glGetProgramInfoLog(program_, logLength, nil, log);
+        WriteLnToConsole('========== Compiler log  ==========');
+        WriteLnToConsole(shortstring(log));
+        WriteLnToConsole('===================================');
+        FreeMem(log, logLength);
+    end;
+
+    if linkResult <> GL_TRUE then
+    begin
+        WriteLnToConsole('Linking program failed, halting');
+        halt(-1);
+    end;
+
+    CompileProgram:= program_;
+end;
+
+{$ENDIF}
+
 procedure SetupOpenGL;
 //var vendor: shortstring = '';
 var buf: array[byte] of char;
-{$IFDEF USE_VIDEO_RECORDING}
-    AuxBufNum: LongInt;
-{$ENDIF}
+{$IFDEF PAS2C}err: GLenum;{$ENDIF}
+{$IFDEF USE_VIDEO_RECORDING}AuxBufNum: LongInt;{$ENDIF}
     tmpstr: AnsiString;
     tmpint: LongInt;
     tmpn: LongInt;
@@ -713,6 +849,19 @@
     buf[0]:= char(0); // avoid compiler hint
     AddFileLog('Setting up OpenGL (using driver: ' + shortstring(SDL_VideoDriverName(buf, sizeof(buf))) + ')');
 
+{$IFDEF WEBGL}
+    if OpenGLSetupedBefore then
+        begin
+        glViewport(0, 0, cScreenWidth, cScreenHeight);
+        hglMatrixMode(MATRIX_MODELVIEW);
+        hglLoadIdentity();
+        hglScalef(2.0 / cScreenWidth, -2.0 / cScreenHeight, 1.0);
+        hglTranslatef(0, -cScreenHeight / 2, 0);
+        exit;
+        end
+    OpenGLSetupedBefore := true;
+{$ENDIF}
+
 {$IFDEF SDL13}
     // this function creates an opengles1.1 context by default on mobile devices
     // unless you un-comment this two attributes
@@ -733,11 +882,12 @@
         end
     else if (MaxTextureSize < 1024) and (MaxTextureSize >= 512) then
         begin
-        cReducedQuality := cReducedQuality or rqNoBackground;  
+        cReducedQuality := cReducedQuality or rqNoBackground;
         AddFileLog('Texture size too small for backgrounds, disabling.');
         end;
 
-(*  // find out which gpu we are using (for extension compatibility maybe?)
+(*
+    // find out which gpu we are using (for extension compatibility maybe?)
 {$IFDEF IPHONEOS}
     vendor:= vendor; // avoid hint
     cGPUVendor:= gvApple;
@@ -764,6 +914,11 @@
     glGetIntegerv(GL_AUX_BUFFERS, @AuxBufNum);
     AddFileLog('  |----- Number of auxiliary buffers: ' + inttostr(AuxBufNum));
 {$ENDIF}
+{$IFDEF PAS2C}
+
+    // doesn't seem to print >256 chars
+    AddFileLogRaw(PChar(glGetString(GL_EXTENSIONS)));
+{$ELSE}
     AddFileLog('  \----- Extensions: ');
 
     // fetch extentions and store them in string
@@ -783,6 +938,7 @@
         tmpint := tmpint + 3;
     end;
     until (tmpint > tmpn);
+{$ENDIF}
     AddFileLog('');
 
     defaultFrame:= 0;
@@ -810,8 +966,42 @@
     end;
 {$ENDIF}
 
-{$IFDEF USE_S3D_RENDERING}
-    if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) then
+{$IFDEF GL2}
+
+{$IFDEF PAS2C}
+    err := glewInit();
+    if err <> GLEW_OK then
+    begin
+        WriteLnToConsole('Failed to initialize GLEW.');
+        halt;
+    end;
+{$ENDIF}
+
+{$IFNDEF PAS2C}
+    if not Load_GL_VERSION_2_0 then
+        halt;
+{$ENDIF}
+
+    shaderWater:= CompileProgram('water');
+    glUseProgram(shaderWater);
+    glUniform1i(glGetUniformLocation(shaderWater, pchar('tex0')), 0);
+    uWaterMVPLocation:= glGetUniformLocation(shaderWater, pchar('mvp'));
+
+    shaderMain:= CompileProgram('default');
+    glUseProgram(shaderMain);
+    glUniform1i(glGetUniformLocation(shaderMain, pchar('tex0')), 0);
+    uMainMVPLocation:= glGetUniformLocation(shaderMain, pchar('mvp'));
+    uMainTintLocation:= glGetUniformLocation(shaderMain, pchar('tint'));
+
+    uCurrentMVPLocation:= uMainMVPLocation;
+
+    Tint(255, 255, 255, 255);
+    UpdateModelviewProjection;
+{$ENDIF}
+
+{$IFNDEF PAS2C}
+{$IFNDEF USE_S3D_RENDERING}
+    if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) or (cStereoMode = smAFR) then
     begin
         // prepare left and right frame buffers and associated textures
         if glLoadExtension('GL_EXT_framebuffer_object') then
@@ -826,19 +1016,33 @@
             cStereoMode:= smNone;
     end;
 {$ENDIF}
+{$ENDIF}
 
-    // set view port to whole window
-    glViewport(0, 0, cScreenWidth, cScreenHeight);
+// set view port to whole window
+glViewport(0, 0, cScreenWidth, cScreenHeight);
 
+{$IFDEF GL2}
+    uMatrix.initModule;
+    hglMatrixMode(MATRIX_MODELVIEW);
+    // prepare default translation/scaling
+    hglLoadIdentity();
+    hglScalef(2.0 / cScreenWidth, -2.0 / cScreenHeight, 1.0);
+    hglTranslatef(0, -cScreenHeight / 2, 0);
+
+    EnableTexture(True);
+
+    glEnableVertexAttribArray(aVertex);
+    glEnableVertexAttribArray(aTexCoord);
+    glGenBuffers(1, @vBuffer);
+    glGenBuffers(1, @tBuffer);
+    glGenBuffers(1, @cBuffer);
+{$ELSE}
     glMatrixMode(GL_MODELVIEW);
     // prepare default translation/scaling
     glLoadIdentity();
     glScalef(2.0 / cScreenWidth, -2.0 / cScreenHeight, 1.0);
     glTranslatef(0, -cScreenHeight / 2, 0);
 
-    // enable alpha blending
-    glEnable(GL_BLEND);
-    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     // disable/lower perspective correction (will not need it anyway)
     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
     // disable dithering
@@ -847,8 +1051,92 @@
     glEnable(GL_TEXTURE_2D);
     glEnableClientState(GL_VERTEX_ARRAY);
     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+{$ENDIF}
+
+    // enable alpha blending
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    // disable/lower perspective correction (will not need it anyway)
 end;
 
+{$IFDEF GL2}
+procedure EnableTexture(enable:Boolean);
+begin
+    if enable then
+        glUniform1i(glGetUniformLocation(shaderMain, pchar('enableTexture')), 1)
+    else
+        glUniform1i(glGetUniformLocation(shaderMain, pchar('enableTexture')), 0);
+end;
+{$ENDIF}
+
+procedure SetTexCoordPointer(p: Pointer; n: Integer);
+begin
+    {$IFDEF GL2}
+    glBindBuffer(GL_ARRAY_BUFFER, tBuffer);
+    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * n * 2, p, GL_STATIC_DRAW);
+    glEnableVertexAttribArray(aTexCoord);
+    glVertexAttribPointer(aTexCoord, 2, GL_FLOAT, GL_FALSE, 0, pointer(0));
+    {$ELSE}
+    glTexCoordPointer(2, GL_FLOAT, 0, p);
+    {$ENDIF}
+end;
+
+procedure SetVertexPointer(p: Pointer; n: Integer);
+begin
+    {$IFDEF GL2}
+    glBindBuffer(GL_ARRAY_BUFFER, vBuffer);
+    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * n * 2, p, GL_STATIC_DRAW);
+    glEnableVertexAttribArray(aVertex);
+    glVertexAttribPointer(aVertex, 2, GL_FLOAT, GL_FALSE, 0, pointer(0));
+    {$ELSE}
+    glVertexPointer(2, GL_FLOAT, 0, p);
+    {$ENDIF}
+end;
+
+procedure SetColorPointer(p: Pointer; n: Integer);
+begin
+    {$IFDEF GL2}
+    glBindBuffer(GL_ARRAY_BUFFER, cBuffer);
+    glBufferData(GL_ARRAY_BUFFER, n * 4, p, GL_STATIC_DRAW);
+    glEnableVertexAttribArray(aColor);
+    glVertexAttribPointer(aColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, pointer(0));
+    {$ELSE}
+    glColorPointer(4, GL_UNSIGNED_BYTE, 0, p);
+    {$ENDIF}
+end;
+
+{$IFDEF GL2}
+procedure UpdateModelviewProjection;
+var
+    mvp: TMatrix4x4f;
+begin
+    //MatrixMultiply(mvp, mProjection, mModelview);
+    hglMVP(mvp);
+    glUniformMatrix4fv(uCurrentMVPLocation, 1, GL_FALSE, @mvp[0, 0]);
+end;
+{$ENDIF}
+
+(*
+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 SetScale(f: GLfloat);
 begin
 // leave immediately if scale factor did not change
@@ -856,18 +1144,62 @@
         exit;
 
     if f = cDefaultZoomLevel then
-        glPopMatrix         // "return" to default scaling
+{$IFDEF GL2}
+        hglPopMatrix         // "return" to default scaling
+{$ELSE}
+        glPopMatrix
+{$ENDIF}
     else                    // other scaling
         begin
+{$IFDEF GL2}
+        hglPushMatrix;       // save default scaling
+        hglLoadIdentity;
+        hglScalef(f / cScreenWidth, -f / cScreenHeight, 1.0);
+        hglTranslatef(0, -cScreenHeight / 2, 0);
+{$ELSE}
         glPushMatrix;       // save default scaling
         glLoadIdentity;
         glScalef(f / cScreenWidth, -f / cScreenHeight, 1.0);
         glTranslatef(0, -cScreenHeight / 2, 0);
+{$ENDIF}
         end;
 
     cScaleFactor:= f;
+
+{$IFDEF GL2}
+    UpdateModelviewProjection;
+{$ENDIF}
 end;
 
+procedure BeginWater;
+begin
+    {$IFDEF GL2}
+    glUseProgram(shaderWater);
+    uCurrentMVPLocation:=uWaterMVPLocation;
+    UpdateModelviewProjection;
+    glDisableVertexAttribArray(aTexCoord);
+    glEnableVertexAttribArray(aColor);
+    {$ELSE}
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    glEnableClientState(GL_COLOR_ARRAY);
+    {$ENDIF}
+end;
+
+procedure EndWater;
+begin
+    {$IFDEF GL2}
+    glUseProgram(shaderMain);
+    uCurrentMVPLocation:=uMainMVPLocation;
+    UpdateModelviewProjection;
+    glDisableVertexAttribArray(aColor);
+    glEnableVertexAttribArray(aTexCoord);
+    {$ELSE}
+    glDisableClientState(GL_COLOR_ARRAY);
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    {$ENDIF}
+end;
+
+
 ////////////////////////////////////////////////////////////////////////////////
 procedure AddProgress;
 var r: TSDL_Rect;
@@ -884,10 +1216,11 @@
         squaresize:= texsurf^.w shr 1;
         numsquares:= texsurf^.h div squaresize;
         SDL_FreeSurface(texsurf);
+        {$IFNDEF PAS2C}
         with mobileRecord do
             if GameLoading <> nil then
                 GameLoading();
-        
+        {$ENDIF}
         end;
 
     TryDo(ProgrTex <> nil, 'Error - Progress Texure is nil!', true);
@@ -905,14 +1238,17 @@
     DrawTextureFromRect( -squaresize div 2, (cScreenHeight - squaresize) shr 1, @r, ProgrTex);
 
     SwapBuffers;
+
     inc(Step);
 end;
 
 procedure FinishProgress;
 begin
+    {$IFNDEF PAS2C}
     with mobileRecord do
         if GameLoaded <> nil then
             GameLoaded();
+    {$ENDIF}
     WriteLnToConsole('Freeing progress surface... ');
     FreeTexture(ProgrTex);
     ProgrTex:= nil;
@@ -1197,10 +1533,12 @@
         //uTextures.freeModule; //DEBUG ONLY
     {$ENDIF}
         AddFileLog('Freeing old primary surface...');
-    {$IFNDEF SDL13}        
+    {$IFNDEF SDL13}
+    {$IFNDEF WEBGL}
         SDL_FreeSurface(SDLPrimSurface);
         SDLPrimSurface:= nil;
     {$ENDIF}
+    {$ENDIF}
 {$ENDIF}
         end;
 
@@ -1253,13 +1591,14 @@
 {$ENDIF}
 
     SetupOpenGL();
+
     if reinit then
         begin
         // clean the window from any previous content
         glClear(GL_COLOR_BUFFER_BIT);
         if SuddenDeathDmg then
             glClearColor(SDSkyColor.r * (SDTint/255) / 255, SDSkyColor.g * (SDTint/255) / 255, SDSkyColor.b * (SDTint/255) / 255, 0.99)
-        else if ((cReducedQuality and rqNoBackground) = 0) then 
+        else if ((cReducedQuality and rqNoBackground) = 0) then
             glClearColor(SkyColor.r / 255, SkyColor.g / 255, SkyColor.b / 255, 0.99)
         else
             glClearColor(RQSkyColor.r / 255, RQSkyColor.g / 255, RQSkyColor.b / 255, 0.99);
@@ -1284,6 +1623,10 @@
     ProgrTex:= nil;
     SupportNPOTT:= false;
 
+{$IFDEF WEBGL}
+    OpenGLSetupedBefore := false;
+{$ENDIF}
+
     // init all ammo name texture pointers
     for ai:= Low(TAmmoType) to High(TAmmoType) do
     begin
@@ -1302,6 +1645,13 @@
 
 procedure freeModule;
 begin
+{$IFDEF GL2}
+    glDeleteProgram(shaderMain);
+    glDeleteProgram(shaderWater);
+    glDeleteBuffers(1, @vBuffer);
+    glDeleteBuffers(1, @tBuffer);
+    glDeleteBuffers(1, @cBuffer);
+{$ENDIF}
     StoreRelease(false);
     TTF_Quit();
 {$IFDEF SDL13}
--- a/hedgewars/uTeams.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uTeams.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -595,8 +595,9 @@
 end;
 
 procedure chBind(var id: shortstring);
-var KeyName, Modifier, tmp: shortstring;
-    b: LongInt;
+var KeyName, Modifier, tmp : shortstring;
+    b              : LongInt;
+    i              : Integer;
 begin
 KeyName:= '';
 Modifier:= '';
@@ -604,7 +605,9 @@
 if CurrentTeam = nil then
     exit;
 
-if(Pos('mod:', id) <> 0)then
+i := Pos('mod:', id);
+
+if(i <> 0)then
     begin
     tmp:= '';
     SplitBySpace(id, tmp);
--- a/hedgewars/uTouch.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uTouch.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -76,20 +76,20 @@
     xTouchClick,yTouchClick : LongInt;
     timeSinceClick : Longword;
 
-    //Pinch to zoom 
+    //Pinch to zoom
     pinchSize : LongInt;
     baseZoomValue: GLFloat;
 
     //aiming
     aimingCrosshair: boolean;
-    aimingUp, aimingDown: boolean; 
+    aimingUp, aimingDown: boolean;
     targetAngle: LongInt;
 
     buttonsDown: Longword;
     targetting, targetted: boolean; //true when targetting an airstrike or the like
 
 procedure onTouchDown(x,y: Longword; pointerId: TSDL_FingerId);
-var 
+var
     finger: PTouch_Data;
 begin
 {$IFDEF USE_TOUCH_INTERFACE}
@@ -161,7 +161,7 @@
             ParseTeamCommand('/timer ' + inttostr((GetCurAmmoEntry(CurrentHedgeHog^)^.Timer div 1000) mod 5 + 1));
         end;
     exit;
-    end; 
+    end;
 dec(buttonsDown);//no buttonsDown, undo the inc() above
 if buttonsDown = 0 then
     begin
@@ -201,8 +201,8 @@
         end;
         exit //todo change into switch rather than ugly ifs
     end;
-    
-if aimingCrosshair then 
+
+if aimingCrosshair then
     begin
         aim(finger^);
         exit
@@ -252,10 +252,10 @@
 if (buttonsDown > 0) and (widget <> nil) then
     begin
     dec(buttonsDown);
-    
+
     if widget = @arrowLeft then
         ParseTeamCommand('-left');
-    
+
     if widget = @arrowRight then
         ParseTeamCommand('-right');
 
@@ -267,7 +267,7 @@
 
     if widget = @fireButton then
         ParseTeamCommand('-attack');
-    
+
     if widget = @utilityWidget then
         if (CurrentHedgehog <> nil)then
             if(Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0)then
@@ -279,10 +279,10 @@
                 ParseTeamCommand('switch')
             else WriteLnToConsole(inttostr(ord(Ammoz[CurrentHedgehog^.CurAmmoType].NameId)) + ' ' + inttostr(ord(sidSwitch)));
     end;
-        
+
 if targetting then
     AddCaption('Press the target button to mark the target', cWhiteColor, capgrpAmmoInfo);
- 
+
 deleteFinger(pointerId);
 {$ENDIF}
 end;
@@ -309,8 +309,8 @@
 //if (RealTicks - timeSinceClick < 300) and (sqrt(sqr(finger.X-xTouchClick) + sqr(finger.Y-yTouchClick)) < 30) then
 //    begin
 //    onTouchDoubleClick(finger);
-//    timeSinceClick:= 0;//we make an assumption there won't be an 'click' in the first 300 ticks(milliseconds) 
-//    exit; 
+//    timeSinceClick:= 0;//we make an assumption there won't be an 'click' in the first 300 ticks(milliseconds)
+//    exit;
 //    end;
 
 xTouchClick:= finger.x;
@@ -318,12 +318,12 @@
 timeSinceClick:= RealTicks;
 
 if bShowAmmoMenu then
-    begin 
+    begin
     if isOnRect(AmmoRect, finger) then
         begin
         CursorPoint.X:= finger.x;
         CursorPoint.Y:= finger.y;
-        ParseTeamCommand('put'); 
+        ParseTeamCommand('put');
         end
     else
         bShowAmmoMenu:= false;
@@ -339,28 +339,28 @@
 
 if isOnWidget(jumpWidget, finger) then
     begin
-    ParseTeamCommand('hjump');    
+    ParseTeamCommand('hjump');
     exit;
     end;
 {$ENDIF}
 end;
 
 function addFinger(x,y: Longword; id: TSDL_FingerId): PTouch_Data;
-var 
+var
     xCursor, yCursor, index : LongInt;
 begin
     //Check array sizes
-    if length(fingers) < Integer(pointerCount) then 
+    if length(fingers) < Integer(pointerCount) then
     begin
         setLength(fingers, length(fingers)*2);
         for index := length(fingers) div 2 to length(fingers) do
             fingers[index].id := nilFingerId;
     end;
-    
-    
+
+
     xCursor := convertToCursorX(x);
     yCursor := convertToCursorY(y);
-    
+
     //on removing fingers, all fingers are moved to the left
     //with dynamic arrays being zero based, the new position of the finger is the old pointerCount
     fingers[pointerCount].id := id;
@@ -372,7 +372,7 @@
     fingers[pointerCount].dy := 0;
     fingers[pointerCount].timeSinceDown:= RealTicks;
     fingers[pointerCount].pressedWidget:= nil;
- 
+
     addFinger:= @fingers[pointerCount];
     inc(pointerCount);
 end;
@@ -391,22 +391,22 @@
 var
     index : Longword;
 begin
-    
+
     dec(pointerCount);
     for index := 0 to pointerCount do
     begin
         if fingers[index].id = id then
         begin
- 
-            //put the last finger into the spot of the finger to be removed, 
+
+            //put the last finger into the spot of the finger to be removed,
             //so that all fingers are packed to the far left
             if  pointerCount <> index then
                 begin
-                fingers[index].id := fingers[pointerCount].id;    
-                fingers[index].x := fingers[pointerCount].x;    
-                fingers[index].y := fingers[pointerCount].y;    
-                fingers[index].historicalX := fingers[pointerCount].historicalX;    
-                fingers[index].historicalY := fingers[pointerCount].historicalY;    
+                fingers[index].id := fingers[pointerCount].id;
+                fingers[index].x := fingers[pointerCount].x;
+                fingers[index].y := fingers[pointerCount].y;
+                fingers[index].historicalX := fingers[pointerCount].historicalX;
+                fingers[index].historicalY := fingers[pointerCount].historicalY;
                 fingers[index].timeSinceDown := fingers[pointerCount].timeSinceDown;
 
                 fingers[pointerCount].id := nilFingerId;
@@ -430,12 +430,12 @@
 var
     deltaAngle: LongInt;
 begin
-invertCursor := not(bShowAmmoMenu or targetting); 
+invertCursor := not(bShowAmmoMenu or targetting);
 if aimingCrosshair then
     if CurrentHedgehog^.Gear <> nil then
         begin
         deltaAngle:= CurrentHedgehog^.Gear^.Angle - targetAngle;
-        if (deltaAngle > -5) and (deltaAngle < 5) then 
+        if (deltaAngle > -5) and (deltaAngle < 5) then
             begin
                 if(aimingUp)then
                     begin
@@ -475,10 +475,10 @@
                     aimingUp:= true;
                     ParseTeamCommand('+up');
                     end;
-                end; 
+                end;
             end;
         end
-    else  
+    else
         begin
         if aimingUp then
             begin
@@ -498,7 +498,7 @@
     index: LongWord;
 begin
     for index := 0 to High(fingers) do
-        if fingers[index].id = id then 
+        if fingers[index].id = id then
             begin
             findFinger := @fingers[index];
             break;
@@ -506,7 +506,7 @@
 end;
 
 procedure aim(finger: TTouch_Data);
-var 
+var
     hogX, hogY, touchX, touchY, deltaX, deltaY: LongInt;
 begin
     if CurrentHedgehog^.Gear <> nil then
@@ -519,7 +519,7 @@
         convertToWorldCoord(touchX, touchY, finger);
         deltaX := abs(TouchX-HogX);
         deltaY := TouchY-HogY;
-        
+
         targetAngle:= (Round(DeltaY / sqrt(sqr(deltaX) + sqr(deltaY)) * 2048) + 2048) div 2;
         end; //if CurrentHedgehog^.Gear <> nil
 end;
@@ -579,9 +579,9 @@
 
 procedure convertToWorldCoord(var x,y: LongInt; finger: TTouch_Data);
 begin
-//if x <> nil then 
+//if x <> nil then
     x := finger.x-WorldDx;
-//if y <> nil then 
+//if y <> nil then
     y := (cScreenHeight - finger.y)-WorldDy;
 end;
 
@@ -637,7 +637,7 @@
     buttonsDown:= 0;
 
     setLength(fingers, 4);
-    for index := 0 to High(fingers) do 
+    for index := 0 to High(fingers) do
         fingers[index].id := nilFingerId;
 
     rectSize:= round(baseRectSize * mobileRecord.getScreenDPI());
--- a/hedgewars/uTypes.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uTypes.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -44,7 +44,8 @@
     // Different files are stored in different folders, this enumeration is used to tell which folder to use
     TPathType = (ptNone, ptData, ptGraphics, ptThemes, ptCurrTheme, ptTeams, ptMaps,
             ptMapCurrent, ptDemos, ptSounds, ptGraves, ptFonts, ptForts,
-            ptLocale, ptAmmoMenu, ptHedgehog, ptVoices, ptHats, ptFlags, ptMissionMaps, ptSuddenDeath, ptButtons);
+            ptLocale, ptAmmoMenu, ptHedgehog, ptVoices, ptHats, ptFlags, ptMissionMaps, ptSuddenDeath, ptButtons,
+            ptShaders);
 
     // Available sprites for displaying stuff
     TSprite = (sprWater, sprCloud, sprBomb, sprBigDigit, sprFrame,
@@ -201,6 +202,8 @@
             X, Y: GLint;
             end;
 
+    TMatrix4x4f = array[0..3, 0..3] of GLfloat;
+
     PTexture = ^TTexture;
     TTexture = record
             id: GLuint;
@@ -401,21 +404,21 @@
     TClan = record
             Color: Longword;
             Teams: array[0..Pred(cMaxTeams)] of PTeam;
-            TeamsNumber: Longword;
+        TeamsNumber: LongInt;{xymeng, org:LongWord}
             TagTeamIndex: Longword;
             CurrTeam: LongWord;
             ClanHealth: LongInt;
             ClanIndex: LongInt;
-            TurnNumber: LongWord;
+        TurnNumber: LongInt;{xymeng, org:LongWord}
             Flawless: boolean;
             end;
 
      cdeclPtr = procedure; cdecl;
      cdeclIntPtr = procedure(num: LongInt); cdecl;
-     functionDoublePtr = function: Double;
+     funcDoublePtr = function: Double;
 
      TMobileRecord = record
-                     getScreenDPI: functionDoublePtr;
+                     getScreenDPI: funcDoublePtr;
                      PerformRumble: cdeclIntPtr;
                      GameLoading: cdeclPtr;
                      GameLoaded: cdeclPtr;
@@ -453,10 +456,12 @@
             gidRandomMineTimer, gidDamageModifier, gidResetHealth, gidAISurvival,
             gidInfAttack, gidResetWeps, gidPerHogAmmo, gidTagTeam);
 
+
     TLandArray = packed array of array of LongWord;
     TCollisionArray = packed array of array of Word;
+    TDirtyTag = packed array of array of byte;
+
     TPreview  = packed array[0..127, 0..31] of byte;
-    TDirtyTag = packed array of array of byte;
 
     PWidgetMovement = ^TWidgetMovement;
     TWidgetMovement = record
--- a/hedgewars/uUtils.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uUtils.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -25,7 +25,10 @@
 
 procedure SplitBySpace(var a, b: shortstring);
 procedure SplitByChar(var a, b: shortstring; c: char);
+
+{$IFNDEF PAS2C}
 procedure SplitByChar(var a, b: ansistring; c: char);
+{$ENDIF}
 
 function  EnumToStr(const en : TGearType) : shortstring; overload;
 function  EnumToStr(const en : TVisualGearType) : shortstring; overload;
@@ -66,8 +69,10 @@
 function  GetLaunchX(at: TAmmoType; dir: LongInt; angle: LongInt): LongInt;
 function  GetLaunchY(at: TAmmoType; angle: LongInt): LongInt;
 
+{$IFNDEF PAS2C}
 procedure Write(var f: textfile; s: shortstring);
 procedure WriteLn(var f: textfile; s: shortstring);
+{$ENDIF}
 
 function  isPhone: Boolean; inline;
 function  getScreenDPI: Double; inline; //cdecl; external;
@@ -88,7 +93,7 @@
 
 
 implementation
-uses typinfo, Math, uConsts, uVariables, SysUtils;
+uses {$IFNDEF PAS2C}typinfo, {$ENDIF}Math, uConsts, uVariables, SysUtils;
 
 {$IFDEF DEBUGFILE}
 var f: textfile;
@@ -96,7 +101,7 @@
     logMutex: TRTLCriticalSection; // mutex for debug file
 {$ENDIF}
 {$ENDIF}
-var CharArray: array[byte] of Char;
+var CharArray: array[0..255] of Char;
 
 procedure SplitBySpace(var a,b: shortstring);
 begin
@@ -115,11 +120,15 @@
             Inc(a[t], 32);
     b:= copy(a, i + 1, Length(a) - i);
     a[0]:= char(Pred(i))
+    {$IFDEF PAS2C}
+       a[i] := 0;
+    {$ENDIF}
     end
 else
     b:= '';
 end;
 
+{$IFNDEF PAS2C}
 procedure SplitByChar(var a, b: ansistring; c: char);
 var i: LongInt;
 begin
@@ -129,7 +138,8 @@
     b:= copy(a, i + 1, Length(a) - i);
     setlength(a, Pred(i));
     end else b:= '';
-end;
+end; { SplitByChar }
+{$ENDIF}
 
 function EnumToStr(const en : TGearType) : shortstring; overload;
 begin
@@ -184,14 +194,18 @@
 str(n, IntToStr)
 end;
 
-function  StrToInt(s: shortstring): LongInt;
+function StrToInt(s: shortstring): LongInt;
 var c: LongInt;
 begin
+{$IFDEF PAS2C}
+val(s, StrToInt);
+{$ELSE}
 val(s, StrToInt, c);
 {$IFDEF DEBUGFILE}
 if c <> 0 then
     writeln(f, 'Error at position ' + IntToStr(c) + ' : ' + s[c])
 {$ENDIF}
+{$ENDIF}
 end;
 
 function FloatToStr(n: hwFloat): shortstring;
@@ -285,10 +299,14 @@
 
 
 function Str2PChar(const s: shortstring): PChar;
+var i :Integer ;
 begin
-CharArray:= s;
+   for i:= 1 to Length(s) do
+      begin
+      CharArray[i - 1] := s[i];
+      end;
 CharArray[Length(s)]:= #0;
-Str2PChar:= @CharArray
+   Str2PChar:= @(CharArray[0]);
 end;
 
 
@@ -307,16 +325,21 @@
 
 procedure AddFileLog(s: shortstring);
 begin
-s:= s;
+// s:= s;
+{$IFNDEF WEBGL}
 {$IFDEF DEBUGFILE}
+
 {$IFDEF USE_VIDEO_RECORDING}
 EnterCriticalSection(logMutex);
 {$ENDIF}
 writeln(f, inttostr(GameTicks)  + ': ' + s);
 flush(f);
+
 {$IFDEF USE_VIDEO_RECORDING}
 LeaveCriticalSection(logMutex);
 {$ENDIF}
+
+{$ENDIF}
 {$ENDIF}
 end;
 
@@ -403,6 +426,7 @@
 CheckNoTeamOrHH:= (CurrentTeam = nil) or (CurrentHedgehog^.Gear = nil);
 end;
 
+{$IFNDEF PAS2C}
 procedure Write(var f: textfile; s: shortstring);
 begin
 system.write(f, s)
@@ -412,7 +436,7 @@
 begin
 system.writeln(f, s)
 end;
-
+{$ENDIF}
 
 // this function is just to determine whether we are running on a limited screen device
 function isPhone: Boolean; inline;
@@ -459,8 +483,12 @@
     if (c < #32) or (c > #127) then
         r:= '#' + inttostr(byte(c))
         else
-        r:= c;
-            
+        begin
+        // some magic for pas2c
+        r[0]:= #1;
+        r[1]:= c;
+        end;
+
     sanitizeCharForLog:= r
 end;
 
--- a/hedgewars/uVariables.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uVariables.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -21,7 +21,7 @@
 unit uVariables;
 interface
 
-uses SDLh, uTypes, uFloat, GLunit, uConsts, Math, uUtils;
+uses SDLh, uTypes, uFloat, GLunit, uConsts, Math, uUtils, uMatrix;
 
 var
 /////// init flags ///////
@@ -77,7 +77,7 @@
 
     CheckSum        : LongWord;
     CampaignVariable: shortstring;
-    GameTicks       : LongWord;
+    GameTicks       : LongInt; {xymeng:originally LongWord}
     GameState       : TGameState;
     GameType        : TGameType;
     InputMask       : LongWord;
@@ -161,7 +161,7 @@
     cArtillery      : boolean;
     WeaponTooltipTex: PTexture;
     AmmoMenuInvalidated: boolean;
-    AmmoRect		: TSDL_Rect;
+    AmmoRect        : TSDL_Rect;
     HHTexture       : PTexture;
     cMaxZoomLevel   : real;
     cMinZoomLevel   : real;
@@ -197,7 +197,7 @@
 
     LuaGoals        : shortstring;
 
-    LuaTemplateNumber : LongWord;
+    LuaTemplateNumber : LongInt; {org: LongWord}
 
     LastVoice : TVoice = ( snd: sndNone; voicepack: nil );
 
@@ -238,9 +238,11 @@
         '/Graphics/Flags',               // ptFlags
         '/Missions/Maps',                // ptMissionMaps
         '/Graphics/SuddenDeath',         // ptSuddenDeath
-        '/Graphics/Buttons'              // ptButton
+        '/Graphics/Buttons',             // ptButton
+        '/Shaders'                       // ptShaders
     );
 
+var
     Fontz: array[THWFont] of THHFont = (
             (Handle: nil;
             Height: 12;
@@ -698,7 +700,7 @@
             TimeAfterTurn: Longword;
             minAngle, maxAngle: Longword;
             isDamaging: boolean;
-            SkipTurns: Longword;
+            SkipTurns: LongInt; {xymeng, orinally: LongWord}
             PosCount: Longword;
             PosSprite: TSprite;
             ejectX, ejectY: Longint;
@@ -731,9 +733,9 @@
             NameTex: nil;
             Probability: 0;
             NumberInCase: 1;
-            Ammo: (Propz: ammoprop_Timerable or 
-                          ammoprop_Power or 
-                          ammoprop_AltUse or 
+            Ammo: (Propz: ammoprop_Timerable or
+                          ammoprop_Power or
+                          ammoprop_AltUse or
                           ammoprop_SetBounce or
                           ammoprop_NeedUpDown;
                 Count: AMMO_INFINITE;
@@ -759,9 +761,9 @@
             NameTex: nil;
             Probability: 100;
             NumberInCase: 3;
-            Ammo: (Propz: ammoprop_Timerable or 
-                          ammoprop_Power or 
-                          ammoprop_AltUse or 
+            Ammo: (Propz: ammoprop_Timerable or
+                          ammoprop_Power or
+                          ammoprop_AltUse or
                           ammoprop_SetBounce or
                           ammoprop_NeedUpDown;
                 Count: 5;
@@ -787,7 +789,7 @@
             NameTex: nil;
             Probability: 0;
             NumberInCase: 1;
-            Ammo: (Propz: ammoprop_Power or 
+            Ammo: (Propz: ammoprop_Power or
                           ammoprop_AltUse or
                           ammoprop_NeedUpDown;
                 Count: AMMO_INFINITE;
@@ -813,8 +815,8 @@
             NameTex: nil;
             Probability: 100;
             NumberInCase: 1;
-            Ammo: (Propz: ammoprop_Power or 
-                          ammoprop_NeedTarget or 
+            Ammo: (Propz: ammoprop_Power or
+                          ammoprop_NeedTarget or
                           ammoprop_DontHold or
                           ammoprop_NeedUpDown;
                 Count: 2;
@@ -865,9 +867,9 @@
             NameTex: nil;
             Probability: 0;
             NumberInCase: 1;
-            Ammo: (Propz: ammoprop_ForwMsgs or 
-                          ammoprop_AttackInMove or 
-                          ammoprop_NoCrosshair or 
+            Ammo: (Propz: ammoprop_ForwMsgs or
+                          ammoprop_AttackInMove or
+                          ammoprop_NoCrosshair or
                           ammoprop_DontHold;
                 Count: 2;
                 NumPerTurn: 0;
@@ -892,7 +894,7 @@
             NameTex: nil;
             Probability: 0;
             NumberInCase: 1;
-            Ammo: (Propz: ammoprop_NoCrosshair or 
+            Ammo: (Propz: ammoprop_NoCrosshair or
                           ammoprop_DontHold;
                 Count: AMMO_INFINITE;
                 NumPerTurn: 0;
@@ -946,10 +948,10 @@
             NameTex: nil;
             Probability: 100;
             NumberInCase: 1;
-            Ammo: (Propz: ammoprop_NoCrosshair or 
-                          ammoprop_AttackInMove or 
-                          ammoprop_DontHold or 
-                          ammoprop_AltUse or 
+            Ammo: (Propz: ammoprop_NoCrosshair or
+                          ammoprop_AttackInMove or
+                          ammoprop_DontHold or
+                          ammoprop_AltUse or
                           ammoprop_SetBounce;
                 Count: 2;
                 NumPerTurn: 0;
@@ -998,9 +1000,9 @@
             NameTex: nil;
             Probability: 100;
             NumberInCase: 1;
-            Ammo: (Propz: ammoprop_NoCrosshair or 
-                          ammoprop_AttackInMove or 
-                          ammoprop_DontHold or 
+            Ammo: (Propz: ammoprop_NoCrosshair or
+                          ammoprop_AttackInMove or
+                          ammoprop_DontHold or
                           ammoprop_AltUse;
                 Count: 1;
                 NumPerTurn: 0;
@@ -1025,8 +1027,8 @@
             NameTex: nil;
             Probability: 0;
             NumberInCase: 1;
-            Ammo: (Propz: ammoprop_NoCrosshair or 
-                          ammoprop_ForwMsgs or 
+            Ammo: (Propz: ammoprop_NoCrosshair or
+                          ammoprop_ForwMsgs or
                           ammoprop_AttackInMove;
                 Count: AMMO_INFINITE;
                 NumPerTurn: 0;
@@ -1321,8 +1323,8 @@
             NameTex: nil;
             Probability: 100;
             NumberInCase: 1;
-            Ammo: (Propz: ammoprop_ForwMsgs or 
-                          ammoprop_DontHold or 
+            Ammo: (Propz: ammoprop_ForwMsgs or
+                          ammoprop_DontHold or
                           ammoprop_NeedUpDown or
                           ammoprop_AttackInMove;
                 Count: 1;
@@ -1348,8 +1350,8 @@
             NameTex: nil;
             Probability: 100;
             NumberInCase: 1;
-            Ammo: (Propz: ammoprop_ForwMsgs or 
-                          ammoprop_NoCrosshair or 
+            Ammo: (Propz: ammoprop_ForwMsgs or
+                          ammoprop_NoCrosshair or
                           ammoprop_DontHold or
                           ammoprop_Track;
                 Count: 1;
@@ -1375,7 +1377,7 @@
             NameTex: nil;
             Probability: 100;
             NumberInCase: 1;
-            Ammo: (Propz: ammoprop_ForwMsgs or 
+            Ammo: (Propz: ammoprop_ForwMsgs or
                           ammoprop_DontHold or
                           ammoprop_NoCrosshair;
                 Count: 1;
@@ -1401,8 +1403,8 @@
             NameTex: nil;
             Probability: 400;
             NumberInCase: 1;
-            Ammo: (Propz: ammoprop_Timerable or 
-                          ammoprop_Power or 
+            Ammo: (Propz: ammoprop_Timerable or
+                          ammoprop_Power or
                           ammoprop_NeedUpDown or
                           ammoprop_AltUse;
                 Count: 0;
@@ -1428,7 +1430,7 @@
             NameTex: nil;
             Probability: 400;
             NumberInCase: 1;
-            Ammo: (Propz: ammoprop_Power or 
+            Ammo: (Propz: ammoprop_Power or
                           ammoprop_NeedUpDown or
                           ammoprop_AltUse;
                 Count: 0;
@@ -1482,7 +1484,7 @@
             NameTex: nil;
             Probability: 300;
             NumberInCase: 1;
-            Ammo: (Propz: ammoprop_Power or 
+            Ammo: (Propz: ammoprop_Power or
                           ammoprop_NeedUpDown or
                           ammoprop_AltUse;
                 Count: AMMO_INFINITE;
@@ -1508,7 +1510,7 @@
             NameTex: nil;
             Probability: 400;
             NumberInCase: 1;
-            Ammo: (Propz: ammoprop_ForwMsgs or 
+            Ammo: (Propz: ammoprop_ForwMsgs or
                           ammoprop_NeedUpDown or
                           ammoprop_DontHold;
                 Count: AMMO_INFINITE;
@@ -1736,7 +1738,7 @@
             NameTex: nil;
             Probability: 20;
             NumberInCase: 2;
-            Ammo: (Propz: ammoprop_NeedUpDown or 
+            Ammo: (Propz: ammoprop_NeedUpDown or
                     ammoprop_OscAim or
                     ammoprop_NoMoveAfter;
                 Count: 2;
@@ -1792,7 +1794,7 @@
             NameTex: nil;
             Probability: 0;
             NumberInCase: 1;
-            Ammo: (Propz: ammoprop_Power or 
+            Ammo: (Propz: ammoprop_Power or
                           ammoprop_NeedUpDown or
                           ammoprop_AltUse;
                 Count: AMMO_INFINITE;
@@ -1901,9 +1903,9 @@
             NameTex: nil;
             Probability: 0;
             NumberInCase: 1;
-            Ammo: (Propz: ammoprop_Timerable or 
-                          ammoprop_Power or 
-                          ammoprop_AltUse or 
+            Ammo: (Propz: ammoprop_Timerable or
+                          ammoprop_Power or
+                          ammoprop_AltUse or
                           ammoprop_NeedUpDown or
                           ammoprop_SetBounce;
                 Count: AMMO_INFINITE;
@@ -1954,7 +1956,7 @@
             NameTex: nil;
             Probability: 20;
             NumberInCase: 1;
-            Ammo: (Propz: ammoprop_ForwMsgs or 
+            Ammo: (Propz: ammoprop_ForwMsgs or
                           ammoprop_NeedUpDown or
                           ammoprop_DontHold;
                 Count: 1;
@@ -2085,7 +2087,7 @@
             NameTex: nil;
             Probability: 0;
             NumberInCase: 1;
-            Ammo: (Propz: ammoprop_Power or 
+            Ammo: (Propz: ammoprop_Power or
                           ammoprop_AltUse or
                           ammoprop_NoRoundEnd;
                 Count: 2;
@@ -2103,7 +2105,7 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater;
-            ejectX: 0; 
+            ejectX: 0;
             ejectY: 0),
 
 // Tardis
@@ -2133,7 +2135,7 @@
             ejectX: 0;
             ejectY: 0),
 
-// Structure      
+// Structure
 {
             (NameId: sidStructure;
             NameTex: nil;
@@ -2161,7 +2163,7 @@
             ejectX: 0;
             ejectY: 0),
 }
-            
+
 // Land Gun
             (NameId: sidLandGun;
             NameTex: nil;
@@ -2191,7 +2193,7 @@
             NameTex: nil;
             Probability: 20;
             NumberInCase: 1;
-            Ammo: (Propz: ammoprop_ForwMsgs or 
+            Ammo: (Propz: ammoprop_ForwMsgs or
                           ammoprop_NeedUpDown or
                           ammoprop_DontHold;
                 Count: 1;
@@ -2290,6 +2292,7 @@
     SyncTexture,
     ConfirmTexture: PTexture;
     cScaleFactor: GLfloat;
+    cStereoDepth: GLfloat;
     SupportNPOTT: Boolean;
     Step: LongInt;
     MissionIcons: PSDL_Surface;
@@ -2313,6 +2316,23 @@
 
     lastTurnChecksum : Longword;
 
+    mModelview: TMatrix4x4f;
+    mProjection: TMatrix4x4f;
+    vBuffer: GLuint; // vertex buffer
+    tBuffer: GLuint; // texture coords buffer
+    cBuffer: GLuint; // color buffer
+
+    uCurrentMVPLocation: GLint;
+
+    uMainMVPLocation: GLint;
+    uMainTintLocation: GLint;
+
+    uWaterMVPLocation: GLint;
+
+    aVertex: GLint;
+    aTexCoord: GLint;
+    aColor: GLint;
+
 var trammo:  array[TAmmoStrId] of ansistring;   // name of the weapon
     trammoc: array[TAmmoStrId] of ansistring;   // caption of the weapon
     trammod: array[TAmmoStrId] of ansistring;   // description of the weapon
@@ -2499,7 +2519,7 @@
     cHasFocus       := true;
     cInactDelay     := 100;
     ReadyTimeLeft   := 0;
-    
+
     disableLandBack := false;
     ScreenFade      := sfNone;
 
@@ -2538,6 +2558,13 @@
     cMapName:= '';
 
     LuaTemplateNumber:= 0;
+    cStereoDepth := 0;
+
+//    MatrixLoadIdentity(mModelview);
+//    MatrixLoadIdentity(mProjection);
+    aVertex:= 0;
+    aTexCoord:= 1;
+    aColor:= 2;
 
     mobileRecord.getScreenDPI:= @getScreenDPI; //TODO: define external function.
     {$IFDEF IPHONEOS}
--- a/hedgewars/uVisualGears.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uVisualGears.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -55,7 +55,7 @@
 implementation
 uses uSound, uVariables, uTextures, uRender, Math, uRenderUtils, uStore, uUtils;
 
-const 
+const
     cExplFrameTicks = 110;
     //cSmokeZ = 499;
 var VGCounter: LongWord;
@@ -85,7 +85,7 @@
 // ==================================================================
 
 // ==================================================================
-const doStepHandlers: array[TVisualGearType] of TVGearStepProcedure =
+const vdoStepHandlers: array[TVisualGearType] of TVGearStepProcedure =
         (
             @doStepFlake,
             @doStepCloud,
@@ -154,7 +154,7 @@
     vgtEvilTrace,
     vgtNote,
     vgtSmoothWindBar])) then
-    
+
         exit;
 
 inc(VGCounter);
@@ -163,7 +163,7 @@
 gear^.X:= real(X);
 gear^.Y:= real(Y);
 gear^.Kind := Kind;
-gear^.doStep:= doStepHandlers[Kind];
+gear^.doStep:= vdoStepHandlers[Kind];
 gear^.State:= 0;
 gear^.Tint:= $FFFFFFFF;
 gear^.uid:= VGCounter;
@@ -368,7 +368,7 @@
                 if random(2) = 0 then
                     dx := -dx;
                 end;
-      vgtNote: 
+      vgtNote:
                 begin
                 dx:= 0.005 * (random(15) + 10);
                 dy:= -0.001 * (random(40) + 20);
@@ -385,7 +385,7 @@
                 Frame:= 7;
                 Angle:= 0;
                 end;
-vgtSmoothWindBar: 
+vgtSmoothWindBar:
                 begin
                 Angle:= hwFloat2Float(cMaxWindSpeed)*2 / 1440; // seems rate below is supposed to change wind bar at 1px per 10ms. Max time, 1440ms. This tries to match the rate of change
                 Tag:= hwRound(cWindSpeed * 72 / cMaxWindSpeed);
@@ -411,7 +411,7 @@
 case Gear^.Kind of
     vgtFlake: if cFlattenFlakes then
         gear^.Layer:= 0
-              else if random(3) = 0 then 
+              else if random(3) = 0 then
                   begin
                   gear^.Scale:= 0.5;
                   gear^.Layer:= 0   // 33% - far back
@@ -702,9 +702,9 @@
                                     DrawTextureCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex);
                                 end;
                vgtSmallDamageTag: DrawTextureCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex);
-               vgtHealthTag: if Gear^.Tex <> nil then 
+               vgtHealthTag: if Gear^.Tex <> nil then
                                begin
-                               if Gear^.Frame = 0 then 
+                               if Gear^.Frame = 0 then
                                    DrawTextureCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex)
                                else
                                    begin
@@ -712,11 +712,11 @@
                                    if Gear^.Angle = 0 then
                                        DrawTexture(round(Gear^.X), round(Gear^.Y), Gear^.Tex)
                                    else
-                                       DrawTexture(round(Gear^.X), round(Gear^.Y), Gear^.Tex, Gear^.Angle); 
+                                       DrawTexture(round(Gear^.X), round(Gear^.Y), Gear^.Tex, Gear^.Angle);
                                    SetScale(zoom)
                                    end
                                end;
-               vgtStraightShot: begin 
+               vgtStraightShot: begin
                                 if Gear^.dX < 0 then
                                     i:= -1
                                 else
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/uWeb.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,174 @@
+
+// defines functions used for web port
+
+unit uWeb;
+interface
+
+type
+    TResourceList = record
+        count : Integer;
+        files : array[0..500] of shortstring;
+    end;
+
+function generateResourceList:TResourceList;
+
+implementation
+
+uses uConsts, uVariables, uTypes;
+
+function readThemeCfg:TResourceList; forward;
+
+function generateResourceList:TResourceList;
+var
+    cfgRes : TResourceList;
+    i,j : Integer;
+    t, t2 : shortstring;
+    si : TSprite;
+    res : TResourceList;
+
+begin
+
+    res.count := 0;
+
+    for i:= 0 to Pred(TeamsCount) do
+        with TeamsArray[i]^ do
+            begin
+                Str(i, t);
+                
+                res.files[res.count] := UserPathz[ptGraves] + '/' + GraveName;
+                res.files[res.count + 1] := UserPathz[ptForts] + '/' + FortName;
+                res.files[res.count + 2] := UserPathz[ptGraphics] + '/' + FortName;
+                res.files[res.count + 3] := UserPathz[ptFlags] + '/' + flag;
+
+                inc(res.count, 4);
+                
+            end;
+            
+    for si:= Low(TSprite) to High(TSprite) do
+    with SpritesData[si] do
+        begin
+            Str(si, t);
+            res.files[res.count] := UserPathz[Path] + '/' + FileName;
+            res.files[res.count + 1] := UserPathz[AltPath] + '/' + FileName;
+            inc(res.count, 2);
+
+        end;
+        
+    for i:= 0 to Pred(ClansCount) do
+    with CLansArray[i]^ do
+    begin
+        for j:= 0 to Pred(TeamsNumber) do
+        begin
+            with Teams[j]^ do
+            begin
+                Str(i, t);
+                Str(j, t2);
+                res.files[res.count] := UserPathz[ptForts] + '/' + FortName;
+                inc(res.count);
+
+            end;
+        end;
+    end;
+    
+    cfgRes := readThemeCfg();
+    
+    for i:= 0 to Pred(cfgRes.count) do
+    begin
+        res.files[res.count] := cfgRes.files[i];
+        inc(res.count);
+    end;
+    
+    res.files[res.count] := UserPathz[ptFlags] + '/cpu';
+    inc(res.count);
+    
+    res.files[res.count] := UserPathz[ptFlags] + '/hedgewars';
+    inc(res.count);
+    
+    res.files[res.count] := UserPathz[ptGraphics] + '/' + cHHFileName;
+    inc(res.count);
+    
+    res.files[res.count] := UserPathz[ptGraphics] + '/Girder';
+    inc(res.count);
+    
+    res.files[res.count] := UserPathz[ptCurrTheme] + '/LandTex';
+    inc(res.count);
+    
+    res.files[res.count] := UserPathz[ptCurrTheme] + '/LandBackTex';
+    inc(res.count);
+    
+    res.files[res.count] := UserPathz[ptCurrTheme] + '/Girder';
+    inc(res.count);
+    
+    res.files[res.count] := UserPathz[ptCurrTheme] + '/Border';
+    inc(res.count);
+    
+    res.files[res.count] := UserPathz[ptMapCurrent] + '/mask';
+    inc(res.count);
+    
+    res.files[res.count] := UserPathz[ptMapCurrent] + '/map';
+    inc(res.count);
+    
+    res.files[res.count] := UserPathz[ptGraphics] + '/missions';
+    inc(res.count);
+    
+    res.files[res.count] := UserPathz[ptGraphics] + '/Progress';
+    inc(res.count);
+        
+    res.files[res.count] := UserPathz[ptGraves] + '/Statue';
+    inc(res.count);
+
+    res.files[res.count] := UserPathz[ptGraphics] + '/' + cCHFileName;
+    inc(res.count);
+
+    generateResourceList:=res;
+end;
+
+function readThemeCfg : TResourceList;
+var
+s,key : shortstring;
+f : TextFile;
+i: Integer;
+res : TResourceList;
+begin
+    s:=Pathz[ptCurrTheme] + '/' + cThemeCFGFilename;
+
+    Assign(f, s);
+    {$I-}
+
+    filemode := 0;
+    Reset(f);
+
+    res.count := 0;
+    
+    while not eof(f) do
+    begin
+    Readln(f, s);
+    
+    if Length(s) = 0 then
+        continue;
+    if s[1] = ';' then
+        continue;
+        
+    i:= Pos('=', s);
+    key:= Trim(Copy(s, 1, Pred(i)));
+    Delete(s, 1, i);
+    
+    if (key = 'object') or (key = 'spray') then
+    begin
+        i:=Pos(',', s);
+        
+        res.files[res.count] := Pathz[ptCurrTheme] + '/' + Trim(Copy(s, 1, Pred(i)));
+        res.files[res.count + 1] := Pathz[ptGraphics] + '/' + Trim(Copy(s, 1, Pred(i)));
+        inc(res.count, 2);
+        
+    end;
+    
+    end;
+
+    close(f);
+    {$I+}
+    
+    readThemeCfg := res;
+end;
+
+end.
--- a/hedgewars/uWorld.pas	Sun Jun 09 12:20:19 2013 +0200
+++ b/hedgewars/uWorld.pas	Sun Jun 09 12:22:53 2013 +0200
@@ -60,9 +60,12 @@
     , uCaptions
     , uCursor
     , uCommands
-{$IFDEF USE_VIDEO_RECORDING}    
+{$IFDEF USE_VIDEO_RECORDING}
     , uVideoRec
-{$ENDIF}    
+{$ENDIF}
+{$IFDEF GL2}
+    , uMatrix
+{$ENDIF}
     ;
 
 var cWaveWidth, cWaveHeight: LongInt;
@@ -439,14 +442,14 @@
     AmmoRect.w:= (BORDERSIZE*2) + (SlotsNumX * AMSlotSize) + (SlotsNumX-1);
     AmmoRect.h:= (BORDERSIZE*2) + (SlotsNumY * AMSlotSize) + (SlotsNumY-1);
     amSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, AmmoRect.w, AmmoRect.h, 32, RMask, GMask, BMask, AMask);
-    
+
     AMRect.x:= BORDERSIZE;
     AMRect.y:= BORDERSIZE;
     AMRect.w:= AmmoRect.w - (BORDERSIZE*2);
     AMRect.h:= AmmoRect.h - (BORDERSIZE*2);
 
     SDL_FillRect(amSurface, @AMRect, SDL_MapRGB(amSurface^.format, 0,0,0));
-    
+
     x:= AMRect.x;
     y:= AMRect.y;
     for i:= 0 to cMaxSlotIndex do
@@ -480,25 +483,25 @@
                     AMFrame:= LongInt(Ammo^[i,t].AmmoType) - 1;
                     if STurns >= 0 then //weapon not usable yet, draw grayed out with turns remaining
                         begin
-                        DrawSpriteFrame2Surf(sprAMAmmosBW, amSurface, x + AMSlotPadding, 
+                        DrawSpriteFrame2Surf(sprAMAmmosBW, amSurface, x + AMSlotPadding,
                                                                  y + AMSlotPadding, AMFrame);
                         if STurns < 100 then
-                            DrawSpriteFrame2Surf(sprTurnsLeft, amSurface, 
-                                x + AMSlotSize-16, 
+                            DrawSpriteFrame2Surf(sprTurnsLeft, amSurface,
+                                x + AMSlotSize-16,
                                 y + AMSlotSize + 1 - 16, STurns);
                         end
                     else //draw colored version
                         begin
-                        DrawSpriteFrame2Surf(sprAMAmmos, amSurface, x + AMSlotPadding, 
+                        DrawSpriteFrame2Surf(sprAMAmmos, amSurface, x + AMSlotPadding,
                                                                y + AMSlotPadding, AMFrame);
                         end;
 {$IFDEF USE_LANDSCAPE_AMMOMENU}
-	    inc(y, AMSlotSize + 1); //the plus one is for the border
+        inc(y, AMSlotSize + 1); //the plus one is for the border
 {$ELSE}
-	    inc(x, AMSlotSize + 1);
+        inc(x, AMSlotSize + 1);
 {$ENDIF}
-	    end;
-	end;
+        end;
+    end;
 {$IFDEF USE_LANDSCAPE_AMMOMENU}
     inc(x, AMSlotSize + 1);
 {$ELSE}
@@ -507,7 +510,7 @@
     end;
 
 for i:= 1 to SlotsNumX -1 do
-DrawLine2Surf(amSurface, i * (AMSlotSize+1)+1, BORDERSIZE, i * (AMSlotSize+1)+1, AMRect.h + BORDERSIZE - AMSlotSize - 2,160,160,160);            
+DrawLine2Surf(amSurface, i * (AMSlotSize+1)+1, BORDERSIZE, i * (AMSlotSize+1)+1, AMRect.h + BORDERSIZE - AMSlotSize - 2,160,160,160);
 for i:= 1 to SlotsNumY -1 do
 DrawLine2Surf(amSurface, BORDERSIZE, i * (AMSlotSize+1)+1, AMRect.w + BORDERSIZE, i * (AMSlotSize+1)+1,160,160,160);
 
@@ -552,8 +555,8 @@
     exit
     end;
 
-//Init the menu 
-if(AmmoMenuInvalidated) then 
+//Init the menu
+if(AmmoMenuInvalidated) then
     begin
     AmmoMenuInvalidated:= false;
     FreeTexture(AmmoMenuTex);
@@ -609,7 +612,7 @@
             begin
             AMShiftX:= Round(AMShiftTargetX * (1 - AMAnimState));
             AMShiftY:= Round(AMShiftTargetY * (1 - AMAnimState));
-            if (AMAnimType and AMTypeMaskAlpha) <> 0 then 
+            if (AMAnimType and AMTypeMaskAlpha) <> 0 then
                 Tint($FF, $ff, $ff, Round($ff * AMAnimState));
             end
         else
@@ -634,10 +637,10 @@
             begin
             AMShiftX:= Round(AMShiftTargetX * AMAnimState);
             AMShiftY:= Round(AMShiftTargetY * AMAnimState);
-            if (AMAnimType and AMTypeMaskAlpha) <> 0 then 
+            if (AMAnimType and AMTypeMaskAlpha) <> 0 then
                 Tint($FF, $ff, $ff, Round($ff * (1-AMAnimState)));
             end
-         else 
+         else
             begin
             AMShiftX:= AMShiftTargetX;
             AMShiftY:= AMShiftTargetY;
@@ -646,10 +649,10 @@
             AMState:= AMHidden;
             end;
     end;
-    
+
 DrawTexture(AmmoRect.x + AMShiftX, AmmoRect.y + AMShiftY, AmmoMenuTex);
 
-if ((AMState = AMHiding) or (AMState = AMShowingUp)) and ((AMAnimType and AMTypeMaskAlpha) <> 0 )then 
+if ((AMState = AMHiding) or (AMState = AMShowingUp)) and ((AMAnimType and AMTypeMaskAlpha) <> 0 )then
     Tint($FF, $ff, $ff, $ff);
 
 Pos:= -1;
@@ -670,15 +673,15 @@
                     begin
                     if (CursorPoint.Y <= (cScreenHeight - AmmoRect.y) - ( g    * (AMSlotSize+1))) and
                        (CursorPoint.Y >  (cScreenHeight - AmmoRect.y) - ((g+1) * (AMSlotSize+1))) and
-                       (CursorPoint.X >  AmmoRect.x                   + ( c    * (AMSlotSize+1))) and 
+                       (CursorPoint.X >  AmmoRect.x                   + ( c    * (AMSlotSize+1))) and
                        (CursorPoint.X <= AmmoRect.x                   + ((c+1) * (AMSlotSize+1))) then
                         begin
                         Slot:= i;
                         Pos:= t;
                         STurns:= Ammoz[Ammo^[i, t].AmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber;
                         if (STurns < 0) and (AMShiftX = 0) and (AMShiftY = 0) then
-                            DrawSprite(sprAMSlot, 
-                                       AmmoRect.x + BORDERSIZE + (c * (AMSlotSize+1)) + AMSlotPadding, 
+                            DrawSprite(sprAMSlot,
+                                       AmmoRect.x + BORDERSIZE + (c * (AMSlotSize+1)) + AMSlotPadding,
                                        AmmoRect.y + BORDERSIZE + (g  * (AMSlotSize+1)) + AMSlotPadding -1, 0);
                         end;
                         inc(g);
@@ -700,15 +703,15 @@
                     begin
                     if (CursorPoint.Y <= (cScreenHeight - AmmoRect.y) - ( c    * (AMSlotSize+1))) and
                        (CursorPoint.Y >  (cScreenHeight - AmmoRect.y) - ((c+1) * (AMSlotSize+1))) and
-                       (CursorPoint.X >  AmmoRect.x                   + ( g    * (AMSlotSize+1))) and 
+                       (CursorPoint.X >  AmmoRect.x                   + ( g    * (AMSlotSize+1))) and
                        (CursorPoint.X <= AmmoRect.x                   + ((g+1) * (AMSlotSize+1))) then
                         begin
                         Slot:= i;
                         Pos:= t;
                         STurns:= Ammoz[Ammo^[i, t].AmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber;
                         if (STurns < 0) and (AMShiftX = 0) and (AMShiftY = 0) then
-                            DrawSprite(sprAMSlot, 
-                                       AmmoRect.x + BORDERSIZE + (g * (AMSlotSize+1)) + AMSlotPadding, 
+                            DrawSprite(sprAMSlot,
+                                       AmmoRect.x + BORDERSIZE + (g * (AMSlotSize+1)) + AMSlotPadding,
                                        AmmoRect.y + BORDERSIZE + (c  * (AMSlotSize+1)) + AMSlotPadding -1, 0);
                         end;
                         inc(g);
@@ -743,7 +746,7 @@
 {$IFDEF USE_TOUCH_INTERFACE}//show the aiming buttons + animation
                 if (Ammo^[Slot, Pos].Propz and ammoprop_NeedUpDown) <> 0 then
                     begin
-                    if not(arrowUp.show) then
+                    if (not arrowUp.show) then
                         begin
                         animateWidget(@arrowUp, true, true);
                         animateWidget(@arrowDown, true, true);
@@ -766,7 +769,7 @@
 
     if (WeaponTooltipTex <> nil) and (AMShiftX = 0) and (AMShiftY = 0) then
 {$IFDEF USE_LANDSCAPE_AMMOMENU}
-        if not isPhone() then
+        if (not isPhone()) then
             ShowWeaponTooltip(-WeaponTooltipTex^.w div 2, AmmoRect.y - WeaponTooltipTex^.h - AMSlotSize);
 {$ELSE}
         ShowWeaponTooltip(AmmoRect.x - WeaponTooltipTex^.w - 3, Min(AmmoRect.y + 1, cScreenHeight - WeaponTooltipTex^.h - 40));
@@ -780,9 +783,9 @@
 end;
 
 procedure DrawWater(Alpha: byte; OffsetY: LongInt);
-var VertexBuffer: array [0..3] of TVertex2f;
-    r: TSDL_Rect;
-    lw, lh: GLfloat;
+var VertexBuffer : array [0..3] of TVertex2f;
+    r        : TSDL_Rect;
+    lw, lh   : GLfloat;
 begin
 if SuddenDeathDmg then
     begin
@@ -819,6 +822,7 @@
         VertexBuffer[3].X:= -lw;
         VertexBuffer[3].Y:= lh;
 
+{$IFNDEF GL2}
         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
         glEnableClientState(GL_COLOR_ARRAY);
         if SuddenDeathDmg then
@@ -832,8 +836,29 @@
 
         glDisableClientState(GL_COLOR_ARRAY);
         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+{$ELSE}
+        UpdateModelviewProjection;
+
+        BeginWater;
+        if SuddenDeathDmg then
+            SetColorPointer(@SDWaterColorArray[0], 4)
+        else
+            SetColorPointer(@WaterColorArray[0], 4);
+
+        SetVertexPointer(@VertexBuffer[0], 4);
+
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+        EndWater;
+{$ENDIF}
+
+        {$IFNDEF GL2}
         glColor4ub($FF, $FF, $FF, $FF); // must not be Tint() as color array seems to stay active and color reset is required
+        {$ENDIF}
+        {$IFNDEF WEBGL}
         glEnable(GL_TEXTURE_2D);
+        {$ENDIF}
     end;
 end;
 
@@ -887,8 +912,13 @@
 TextureBuffer[3].Y:= TextureBuffer[2].Y;
 
 
-glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
-glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]);
+SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer));
+SetTexCoordPointer(@TextureBuffer[0], Length(VertexBuffer));
+
+{$IFDEF GL2}
+UpdateModelviewProjection;
+{$ENDIF}
+
 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
 
 Tint($FF, $FF, $FF, $FF);
@@ -1100,12 +1130,19 @@
     else if rm = rmLeftEye then
         d:= -d;
     stereoDepth:= stereoDepth + d;
+
+    {$IFDEF GL2}
+    hglMatrixMode(MATRIX_PROJECTION);
+    hglTranslatef(d, 0, 0);
+    hglMatrixMode(MATRIX_MODELVIEW);
+    {$ELSE}
     glMatrixMode(GL_PROJECTION);
     glTranslatef(d, 0, 0);
     glMatrixMode(GL_MODELVIEW);
+    {$ENDIF}
 {$ENDIF}
 end;
- 
+
 procedure ResetDepth(rm: TRenderMode);
 begin
 {$IFNDEF USE_S3D_RENDERING}
@@ -1114,13 +1151,19 @@
 {$ELSE}
     if rm = rmDefault then
         exit;
+    {$IFDEF GL2}
+    hglMatrixMode(MATRIX_PROJECTION);
+    hglTranslatef(-stereoDepth, 0, 0);
+    hglMatrixMode(MATRIX_MODELVIEW);
+    {$ELSE}
     glMatrixMode(GL_PROJECTION);
     glTranslatef(-stereoDepth, 0, 0);
     glMatrixMode(GL_MODELVIEW);
-    stereoDepth:= 0;
+    {$ENDIF}
+    cStereoDepth:= 0;
 {$ENDIF}
 end;
- 
+
 procedure DrawWorldStereo(Lag: LongInt; RM: TRenderMode);
 var i, t, h: LongInt;
     r: TSDL_Rect;
@@ -1158,7 +1201,7 @@
 if (cReducedQuality and rq2DWater) = 0 then
     begin
         // Waves
-        DrawWater(255, SkyOffset); 
+        DrawWater(255, SkyOffset);
         ChangeDepth(RM, -cStereo_Water_distant);
         DrawWaves( 1,  0 - WorldDx div 32, - cWaveHeight + offsetY div 35, 64);
         ChangeDepth(RM, -cStereo_Water_distant);
@@ -1177,6 +1220,30 @@
 
     DrawWater(255, 0);
 
+(*
+// Attack bar
+    if CurrentTeam <> nil then
+        case AttackBar of
+        //1: begin
+        //r:= StuffPoz[sPowerBar];
+        //{$WARNINGS OFF}
+        //r.w:= (CurrentHedgehog^.Gear^.Power * 256) div cPowerDivisor;
+        //{$WARNINGS ON}
+        //DrawSpriteFromRect(r, cScreenWidth - 272, cScreenHeight - 48, 16, 0, Surface);
+        //end;
+        2: with CurrentHedgehog^ do
+                begin
+                tdx:= hwSign(Gear^.dX) * Sin(Gear^.Angle * Pi / cMaxAngle);
+                tdy:= - Cos(Gear^.Angle * Pi / cMaxAngle);
+                for i:= (Gear^.Power * 24) div cPowerDivisor downto 0 do
+                    DrawSprite(sprPower,
+                            hwRound(Gear^.X) + GetLaunchX(CurAmmoType, hwSign(Gear^.dX), Gear^.Angle) + LongInt(round(WorldDx + tdx * (24 + i * 2))) - 16,
+                            hwRound(Gear^.Y) + GetLaunchY(CurAmmoType, Gear^.Angle) + LongInt(round(WorldDy + tdy * (24 + i * 2))) - 16,
+                            i)
+                end
+        end;
+*)
+
 DrawVisualGears(1);
 DrawGears;
 DrawVisualGears(6);
@@ -1251,7 +1318,7 @@
         i:= Succ(Pred(ReadyTimeLeft) div 1000)
     else
         i:= Succ(Pred(TurnTimeLeft) div 1000);
-   
+
     if i>99 then
         t:= 112
     else if i>9 then
@@ -1322,7 +1389,7 @@
         r.w:= 3;
         DrawTextureFromRect(TeamHealthBarWidth + 15, cScreenHeight + DrawHealthY + smallScreenOffset, @r, HealthTex);
 
-        if not highlight and (not hasGone) then
+        if (not highlight) and (not hasGone) then
             for i:= 0 to cMaxHHIndex do
                 if Hedgehogs[i].Gear <> nil then
                     begin
@@ -1424,14 +1491,14 @@
         AMAnimStartTime:= RealTicks - (AMAnimDuration - (RealTicks - AMAnimStartTime));
     AMState:= AMShowingUp;
     end;
-if not(bShowAmmoMenu) and ((AMstate = AMShowing) or (AMState = AMShowingUp)) then
+if (not bShowAmmoMenu) and ((AMstate = AMShowing) or (AMState = AMShowingUp)) then
     begin
     if (AMState = AMShowing) then
         AMAnimStartTime:= RealTicks
     else
         AMAnimStartTime:= RealTicks - (AMAnimDuration - (RealTicks - AMAnimStartTime));
     AMState:= AMHiding;
-    end; 
+    end;
 
 if bShowAmmoMenu or (AMState = AMHiding) then
     ShowAmmoMenu;
@@ -1443,12 +1510,13 @@
 // Chat
 DrawChat;
 
+
 // various captions
 if fastUntilLag then
     DrawTextureCentered(0, (cScreenHeight shr 1), SyncTexture);
 if isPaused then
     DrawTextureCentered(0, (cScreenHeight shr 1), PauseTexture);
-if not isFirstFrame and (missionTimer <> 0) or isPaused or fastUntilLag or (GameState = gsConfirm) then
+if (not isFirstFrame) and (missionTimer <> 0) or isPaused or fastUntilLag or (GameState = gsConfirm) then
     begin
     if (ReadyTimeLeft = 0) and (missionTimer > 0) then
         dec(missionTimer, Lag);
@@ -1484,8 +1552,8 @@
         if t < 10 then
             s:= '0' + s;
         s:= inttostr(i div 60) + ':' + s;
-   
-    
+
+
         tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(s), cWhiteColorChannels);
         tmpSurface:= doSurfaceConversion(tmpSurface);
         FreeTexture(timeTexture);
@@ -1521,7 +1589,7 @@
 
 if ScreenFade <> sfNone then
     begin
-    if not isFirstFrame then
+    if (not isFirstFrame) then
         case ScreenFade of
             sfToBlack, sfToWhite:     if ScreenFadeValue + Lag * ScreenFadeSpeed < sfMax then
                                           inc(ScreenFadeValue, Lag * ScreenFadeSpeed)
@@ -1551,11 +1619,11 @@
         glDisable(GL_TEXTURE_2D);
 
         glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
-        glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
+        glDrawArrays(GL_TRIANGLE_FAN, 0, High(VertexBuffer) - Low(VertexBuffer) + 1);
 
         glEnable(GL_TEXTURE_2D);
         Tint($FF, $FF, $FF, $FF);
-        if not isFirstFrame and ((ScreenFadeValue = 0) or (ScreenFadeValue = sfMax)) then
+        if (not isFirstFrame) and ((ScreenFadeValue = 0) or (ScreenFadeValue = sfMax)) then
             ScreenFade:= sfNone
         end
     end;
@@ -1576,7 +1644,7 @@
     DrawTexture( -(cScreenWidth shr 1) + 50, 20, recTexture);
 
     // draw red circle
-    glDisable(GL_TEXTURE_2D); 
+    glDisable(GL_TEXTURE_2D);
     Tint($FF, $00, $00, Byte(Round(127*(1 + sin(SDL_GetTicks()*0.007)))));
     glBegin(GL_POLYGON);
     for i:= 0 to 20 do
@@ -1615,7 +1683,7 @@
 // Cursor
 if isCursorVisible then
     begin
-    if not bShowAmmoMenu then
+    if (not bShowAmmoMenu) then
         begin
         if not CurrentTeam^.ExtDriven then TargetCursorPoint:= CursorPoint;
         with CurrentHedgehog^ do
@@ -1631,6 +1699,7 @@
         DrawSprite(sprArrow, TargetCursorPoint.X, cScreenHeight - TargetCursorPoint.Y, (RealTicks shr 6) mod 8)
         end
     end;
+
 isFirstFrame:= false
 end;
 
@@ -1644,7 +1713,7 @@
     uCursor.updatePosition();
 {$ENDIF}
 z:= round(200/zoom);
-if not PlacingHogs and (FollowGear <> nil) and (not isCursorVisible) and (not bShowAmmoMenu) and (not fastUntilLag) and autoCameraOn then
+if (not PlacingHogs) and (FollowGear <> nil) and (not isCursorVisible) and (not bShowAmmoMenu) and (not fastUntilLag) and autoCameraOn then
     if ((abs(CursorPoint.X - prevPoint.X) + abs(CursorPoint.Y - prevpoint.Y)) > 4) then
         begin
         FollowGear:= nil;
@@ -1685,7 +1754,7 @@
     {$ENDIF}
 
 {$ENDIF}
-    if CursorPoint.X < AmmoRect.x + amNumOffsetX + 3 then//check left 
+    if CursorPoint.X < AmmoRect.x + amNumOffsetX + 3 then//check left
         CursorPoint.X:= AmmoRect.x + amNumOffsetX + 3;
     if CursorPoint.X > AmmoRect.x + AmmoRect.w - 3 then//check right
         CursorPoint.X:= AmmoRect.x + AmmoRect.w - 3;
@@ -1814,10 +1883,10 @@
 
 {$IFDEF USE_VIDEO_RECORDING}
 // do not change volume during prerecording as it will affect sound in video file
-if not flagPrerecording then
+if (not flagPrerecording) then
 {$ENDIF}
     begin
-    if not cHasFocus then DampenAudio()
+    if (not cHasFocus) then DampenAudio()
     else UndampenAudio();
     end;
 end;
@@ -1833,7 +1902,7 @@
         begin
         utilityWidget.sprite:= sprTimerButton;
         animateWidget(@utilityWidget, true, true);
-        end 
+        end
     else if (Ammoz[ammoType].Ammo.Propz and ammoprop_NeedTarget) <> 0 then
         begin
         utilityWidget.sprite:= sprTargetButton;
@@ -1857,7 +1926,7 @@
     begin
     show:= showWidget;
     if fade then fadeAnimStart:= RealTicks;
-    
+
     with moveAnim do
         begin
         animate:= true;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/videorec/avwrapper.c	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,509 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdarg.h>
+#include "libavformat/avformat.h"
+#include "libavutil/mathematics.h"
+
+#ifndef AVIO_FLAG_WRITE
+#define AVIO_FLAG_WRITE AVIO_WRONLY
+#endif
+
+static AVFormatContext* g_pContainer;
+static AVOutputFormat* g_pFormat;
+static AVStream* g_pAStream;
+static AVStream* g_pVStream;
+static AVFrame* g_pAFrame;
+static AVFrame* g_pVFrame;
+static AVCodec* g_pACodec;
+static AVCodec* g_pVCodec;
+static AVCodecContext* g_pAudio;
+static AVCodecContext* g_pVideo;
+
+static int g_Width, g_Height;
+static uint32_t g_Frequency, g_Channels;
+static int g_VQuality;
+static AVRational g_Framerate;
+
+static FILE* g_pSoundFile;
+static int16_t* g_pSamples;
+static int g_NumSamples;
+
+
+#if LIBAVCODEC_VERSION_MAJOR < 54
+#define OUTBUFFER_SIZE 200000
+static uint8_t g_OutBuffer[OUTBUFFER_SIZE];
+#endif
+
+// pointer to function from hwengine (uUtils.pas)
+static void (*AddFileLogRaw)(const char* pString);
+
+static void FatalError(const char* pFmt, ...)
+{
+    char Buffer[1024];
+    va_list VaArgs;
+
+    va_start(VaArgs, pFmt);
+    vsnprintf(Buffer, 1024, pFmt, VaArgs);
+    va_end(VaArgs);
+
+    AddFileLogRaw("Error in av-wrapper: ");
+    AddFileLogRaw(Buffer);
+    AddFileLogRaw("\n");
+    exit(1);
+}
+
+// Function to be called from libav for logging.
+// Note: libav can call LogCallback from different threads
+// (there is mutex in AddFileLogRaw).
+static void LogCallback(void* p, int Level, const char* pFmt, va_list VaArgs)
+{
+    char Buffer[1024];
+
+    vsnprintf(Buffer, 1024, pFmt, VaArgs);
+    AddFileLogRaw(Buffer);
+}
+
+static void Log(const char* pFmt, ...)
+{
+    char Buffer[1024];
+    va_list VaArgs;
+
+    va_start(VaArgs, pFmt);
+    vsnprintf(Buffer, 1024, pFmt, VaArgs);
+    va_end(VaArgs);
+
+    AddFileLogRaw(Buffer);
+}
+
+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");
+        return;
+    }
+    g_pAStream->id = 1;
+
+    g_pAudio = g_pAStream->codec;
+
+    avcodec_get_context_defaults3(g_pAudio, g_pACodec);
+    g_pAudio->codec_id = g_pACodec->id;
+
+    // put parameters
+    g_pAudio->sample_fmt = AV_SAMPLE_FMT_S16;
+    g_pAudio->sample_rate = g_Frequency;
+    g_pAudio->channels = g_Channels;
+
+    // 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->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;
+
+    // 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)
+#else
+    if (g_pAudio->frame_size == 0)
+#endif
+        g_NumSamples = 4096;
+    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();
+    if (!g_pAFrame)
+    {
+        Log("Could not allocate frame\n");
+        return;
+    }
+}
+
+// returns non-zero if there is more sound
+static int WriteAudioFrame()
+{
+    if (!g_pAStream)
+        return 0;
+
+    AVPacket Packet = { 0 };
+    av_init_packet(&Packet);
+
+    int NumSamples = fread(g_pSamples, 2*g_Channels, g_NumSamples, g_pSoundFile);
+
+#if LIBAVCODEC_VERSION_MAJOR >= 53
+    AVFrame* pFrame = NULL;
+    if (NumSamples > 0)
+    {
+        g_pAFrame->nb_samples = NumSamples;
+        avcodec_fill_audio_frame(g_pAFrame, g_Channels, AV_SAMPLE_FMT_S16,
+                                 (uint8_t*)g_pSamples, NumSamples*2*g_Channels, 1);
+        pFrame = g_pAFrame;
+    }
+    // when NumSamples == 0 we still need to call encode_audio2 to flush
+    int got_packet;
+    if (avcodec_encode_audio2(g_pAudio, &Packet, pFrame, &got_packet) != 0)
+        FatalError("avcodec_encode_audio2 failed");
+    if (!got_packet)
+        return 0;
+#else
+    if (NumSamples == 0)
+        return 0;
+    int BufferSize = OUTBUFFER_SIZE;
+    if (g_pAudio->frame_size == 0)
+        BufferSize = NumSamples*g_Channels*2;
+    Packet.size = avcodec_encode_audio(g_pAudio, g_OutBuffer, BufferSize, g_pSamples);
+    if (Packet.size == 0)
+        return 1;
+    if (g_pAudio->coded_frame && g_pAudio->coded_frame->pts != AV_NOPTS_VALUE)
+        Packet.pts = av_rescale_q(g_pAudio->coded_frame->pts, g_pAudio->time_base, g_pAStream->time_base);
+    Packet.flags |= AV_PKT_FLAG_KEY;
+    Packet.data = g_OutBuffer;
+#endif
+
+    // Write the compressed frame to the media file.
+    Packet.stream_index = g_pAStream->index;
+    if (av_interleaved_write_frame(g_pContainer, &Packet) != 0) 
+        FatalError("Error while writing audio frame");
+    return 1;
+}
+
+// add a video output stream
+static void 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)
+        FatalError("Could not allocate video stream");
+
+    g_pVideo = g_pVStream->codec;
+
+    avcodec_get_context_defaults3(g_pVideo, g_pVCodec);
+    g_pVideo->codec_id = g_pVCodec->id;
+
+    // put parameters
+    // resolution must be a multiple of two
+    g_pVideo->width  = g_Width  & ~1; // make even (dimensions should be even)
+    g_pVideo->height = g_Height & ~1; // make even
+    /* time base: this is the fundamental unit of time (in seconds) in terms
+       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;
+
+    // set quality
+    if (g_VQuality > 100)
+        g_pVideo->bit_rate = g_VQuality;
+    else
+    {
+        g_pVideo->flags |= 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;
+
+#if LIBAVCODEC_VERSION_MAJOR < 53
+    // for some versions of ffmpeg x264 options must be set explicitly
+    if (strcmp(g_pVCodec->name, "libx264") == 0)
+    {
+        g_pVideo->coder_type = FF_CODER_TYPE_AC;
+        g_pVideo->flags |= CODEC_FLAG_LOOP_FILTER;
+        g_pVideo->crf = 23;
+        g_pVideo->thread_count = 3;
+        g_pVideo->me_cmp = FF_CMP_CHROMA;
+        g_pVideo->partitions = X264_PART_I8X8 | X264_PART_I4X4 | X264_PART_P8X8 | X264_PART_B8X8;
+        g_pVideo->me_method = ME_HEX;
+        g_pVideo->me_subpel_quality = 7;
+        g_pVideo->me_range = 16;
+        g_pVideo->gop_size = 250;
+        g_pVideo->keyint_min = 25;
+        g_pVideo->scenechange_threshold = 40;
+        g_pVideo->i_quant_factor = 0.71;
+        g_pVideo->b_frame_strategy = 1;
+        g_pVideo->qcompress = 0.6;
+        g_pVideo->qmin = 10;
+        g_pVideo->qmax = 51;
+        g_pVideo->max_qdiff = 4;
+        g_pVideo->max_b_frames = 3;
+        g_pVideo->refs = 3;
+        g_pVideo->directpred = 1;
+        g_pVideo->trellis = 1;
+        g_pVideo->flags2 = CODEC_FLAG2_BPYRAMID | CODEC_FLAG2_MIXED_REFS | CODEC_FLAG2_WPRED | CODEC_FLAG2_8X8DCT | CODEC_FLAG2_FASTPSKIP;
+        g_pVideo->weighted_p_pred = 2;
+    }
+#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
+        FatalError("Could not open video codec %s", g_pVCodec->long_name);
+
+    g_pVFrame = avcodec_alloc_frame();
+    if (!g_pVFrame)
+        FatalError("Could not allocate frame");
+
+    g_pVFrame->linesize[0] = g_Width;
+    g_pVFrame->linesize[1] = g_Width/2;
+    g_pVFrame->linesize[2] = g_Width/2;
+    g_pVFrame->linesize[3] = 0;
+}
+
+static int WriteFrame(AVFrame* pFrame)
+{
+    double AudioTime, VideoTime;
+
+    // write interleaved audio frame
+    if (g_pAStream)
+    {
+        VideoTime = (double)g_pVStream->pts.val*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;
+        while (AudioTime < VideoTime && WriteAudioFrame());
+    }
+    
+    if (!g_pVStream)
+        return 0;
+
+    AVPacket Packet;
+    av_init_packet(&Packet);
+    Packet.data = NULL;
+    Packet.size = 0;
+
+    g_pVFrame->pts++;
+    if (g_pFormat->flags & AVFMT_RAWPICTURE)
+    {
+        /* raw video case. The API will change slightly in the near
+           future for that. */
+        Packet.flags |= AV_PKT_FLAG_KEY;
+        Packet.stream_index = g_pVStream->index;
+        Packet.data = (uint8_t*)pFrame;
+        Packet.size = sizeof(AVPicture);
+
+        if (av_interleaved_write_frame(g_pContainer, &Packet) != 0)
+            FatalError("Error while writing video frame");
+        return 0;
+    }
+    else
+    {
+#if LIBAVCODEC_VERSION_MAJOR >= 54
+        int got_packet;
+        if (avcodec_encode_video2(g_pVideo, &Packet, pFrame, &got_packet) < 0)
+            FatalError("avcodec_encode_video2 failed");
+        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);
+#else 
+        Packet.size = avcodec_encode_video(g_pVideo, g_OutBuffer, OUTBUFFER_SIZE, pFrame);
+        if (Packet.size < 0)
+            FatalError("avcodec_encode_video failed");
+        if (Packet.size == 0)
+            return 0;
+
+        if( g_pVideo->coded_frame->pts != AV_NOPTS_VALUE)
+            Packet.pts = av_rescale_q(g_pVideo->coded_frame->pts, g_pVideo->time_base, g_pVStream->time_base);
+        if( g_pVideo->coded_frame->key_frame )
+            Packet.flags |= AV_PKT_FLAG_KEY;
+        Packet.data = g_OutBuffer;
+#endif
+        // write the compressed frame in the media file
+        Packet.stream_index = g_pVStream->index;
+        if (av_interleaved_write_frame(g_pContainer, &Packet) != 0)
+            FatalError("Error while writing video frame");
+            
+        return 1;
+    }
+}
+
+void AVWrapper_WriteFrame(uint8_t* pY, uint8_t* pCb, uint8_t* pCr)
+{
+    g_pVFrame->data[0] = pY;
+    g_pVFrame->data[1] = pCb;
+    g_pVFrame->data[2] = pCr;
+    WriteFrame(g_pVFrame);
+}
+
+void AVWrapper_Init(
+         void (*pAddFileLogRaw)(const char*),
+         const char* pFilename,
+         const char* pDesc,
+         const char* pSoundFile,
+         const char* pFormatName,
+         const char* pVCodecName,
+         const char* pACodecName,
+         int Width, int Height,
+         int FramerateNum, int FramerateDen,
+         int VQuality)
+{    
+    AddFileLogRaw = pAddFileLogRaw;
+    av_log_set_callback( &LogCallback );
+
+    g_Width  = Width;
+    g_Height = Height;
+    g_Framerate.num = FramerateNum;
+    g_Framerate.den = FramerateDen;
+    g_VQuality = VQuality;
+
+    // initialize libav and register all codecs and formats
+    av_register_all();
+
+    // find format
+    g_pFormat = av_guess_format(pFormatName, NULL, NULL);
+    if (!g_pFormat)
+        FatalError("Format \"%s\" was not found", pFormatName);
+
+    // allocate the output media context
+    g_pContainer = avformat_alloc_context();
+    if (!g_pContainer)
+        FatalError("Could not allocate output context");
+
+    g_pContainer->oformat = g_pFormat;
+
+    // store description of file
+    av_dict_set(&g_pContainer->metadata, "comment", pDesc, 0);
+
+    // append extesnion to filename
+    char ext[16];
+    strncpy(ext, g_pFormat->extensions, 16);
+    ext[15] = 0;
+    ext[strcspn(ext,",")] = 0;
+    snprintf(g_pContainer->filename, sizeof(g_pContainer->filename), "%s.%s", pFilename, ext);
+
+    // find codecs
+    g_pVCodec = avcodec_find_encoder_by_name(pVCodecName);
+    g_pACodec = avcodec_find_encoder_by_name(pACodecName);
+
+    // add audio and video stream to container
+    g_pVStream = NULL;
+    g_pAStream = NULL;
+
+    if (g_pVCodec)
+        AddVideoStream();
+    else
+        Log("Video codec \"%s\" was not found; video will be ignored.\n", pVCodecName);
+
+    if (g_pACodec)
+    {
+        g_pSoundFile = fopen(pSoundFile, "rb");
+        if (g_pSoundFile)
+        {
+            fread(&g_Frequency, 4, 1, g_pSoundFile);
+            fread(&g_Channels, 4, 1, g_pSoundFile);
+            AddAudioStream();
+        }
+        else
+            Log("Could not open %s\n", pSoundFile);
+    }
+    else
+        Log("Audio codec \"%s\" was not found; audio will be ignored.\n", pACodecName);
+
+    if (!g_pAStream && !g_pVStream)
+        FatalError("No video, no audio, aborting...");
+
+    // write format info to log
+    av_dump_format(g_pContainer, 0, g_pContainer->filename, 1);
+
+    // open the output file, if needed
+    if (!(g_pFormat->flags & AVFMT_NOFILE))
+    {
+        if (avio_open(&g_pContainer->pb, g_pContainer->filename, AVIO_FLAG_WRITE) < 0)
+            FatalError("Could not open output file (%s)", g_pContainer->filename);
+    }
+
+    // write the stream header, if any
+    avformat_write_header(g_pContainer, NULL);
+
+    g_pVFrame->pts = -1;
+}
+
+void AVWrapper_Close()
+{
+    // output buffered frames
+    if (g_pVCodec->capabilities & CODEC_CAP_DELAY)
+        while( WriteFrame(NULL) );
+    // output any remaining audio
+    while( WriteAudioFrame() );
+
+    // write the trailer, if any.
+    av_write_trailer(g_pContainer);
+
+    // close the output file
+    if (!(g_pFormat->flags & AVFMT_NOFILE))
+        avio_close(g_pContainer->pb);
+
+    // free everything
+    if (g_pVStream)
+    {
+        avcodec_close(g_pVideo);
+        av_free(g_pVideo);
+        av_free(g_pVStream);
+        av_free(g_pVFrame);
+    }
+    if (g_pAStream)
+    {
+        avcodec_close(g_pAudio);
+        av_free(g_pAudio);
+        av_free(g_pAStream);
+        av_free(g_pAFrame);
+        av_free(g_pSamples);
+        fclose(g_pSoundFile);
+    }
+
+    av_free(g_pContainer);
+}
--- a/misc/liblua/CMakeLists.txt	Sun Jun 09 12:20:19 2013 +0200
+++ b/misc/liblua/CMakeLists.txt	Sun Jun 09 12:22:53 2013 +0200
@@ -1,5 +1,7 @@
 #this file is included only when system Lua library is not found
 
+#TODO: when NOPASCAL=1 it should use clang here too
+
 file(GLOB lua_src *.c *.h)
 
 if(WIN32)
--- a/misc/libopenalbridge/CMakeLists.txt	Sun Jun 09 12:20:19 2013 +0200
+++ b/misc/libopenalbridge/CMakeLists.txt	Sun Jun 09 12:22:53 2013 +0200
@@ -15,14 +15,14 @@
 #visualstudio and windows in general don't like static linking, so we're building the library in shared mode
 if(WIN32)
 #workaround for visualstudio (wants headers in the source list)
-	set(openal_src *.h ${openal_src})
+    set(openal_src *.h ${openal_src})
 #deps for the shared library
-	link_libraries(${VORBISFILE_LIBRARY})
-	link_libraries(${VORBIS_LIBRARY})
-	link_libraries(${OGG_LIBRARY})
-	link_libraries(${OPENAL_LIBRARY})
+    link_libraries(${VORBISFILE_LIBRARY})
+    link_libraries(${VORBIS_LIBRARY})
+    link_libraries(${OGG_LIBRARY})
+    link_libraries(${OPENAL_LIBRARY})
 #build a shared library
-	set (build_type SHARED)
+    set (build_type SHARED)
 endif()
 
 #compiles and links actual library
@@ -30,13 +30,13 @@
 
 if(WIN32)
 if(MSVC)
-	set_target_properties(openalbridge PROPERTIES LINK_FLAGS /DEF:openalbridge.def)
+    set_target_properties(openalbridge PROPERTIES LINK_FLAGS /DEF:openalbridge.def)
 endif(MSVC)
 #install it in the executable directory
-	install(TARGETS openalbridge DESTINATION bin)
+    install(TARGETS openalbridge DESTINATION bin)
 endif(WIN32)
 
 #type make openalbridge_test to get a small executable test
-add_executable(openalbridge_test "${hedgewars_SOURCE_DIR}/misc/libopenalbridge/tester.c")
+add_executable(openalbridge_test "${CMAKE_SOURCE_DIR}/misc/libopenalbridge/tester.c")
 target_link_libraries(openalbridge_test openalbridge ${OPENAL_LIBRARY} ${OGGVORBIS_LIBRARIES})
 
--- a/project_files/Android-build/CMakeLists.txt	Sun Jun 09 12:20:19 2013 +0200
+++ b/project_files/Android-build/CMakeLists.txt	Sun Jun 09 12:22:53 2013 +0200
@@ -26,7 +26,7 @@
 endif()
 
 if(IS_DIRECTORY "${ANDROID_NDK}")
-    message(STATUS "Detected the android NDK directory at: " ${ANDROID_NDK}) 
+    message(STATUS "Detected the android NDK directory at: " ${ANDROID_NDK})
 else ()
     message(FATAL_ERROR "Couldn't detect the Android NDK directory")
 endif()
@@ -39,7 +39,7 @@
 endif()
 
 if(IS_DIRECTORY "${ANDROID_NDK_TOOLCHAINDIR}")
-    message(STATUS "Detected the Android NDK toolchain at: ${ANDROID_NDK_TOOLCHAINDIR}") 
+    message(STATUS "Detected the Android NDK toolchain at: ${ANDROID_NDK_TOOLCHAINDIR}")
 else ()
     message(FATAL_ERROR "Couldn't detect the Android NDK toolchain directory: ${ANDROID_NDK_TOOLCHAINDIR}")
 endif()
@@ -52,7 +52,7 @@
 endif()
 
 if( IS_DIRECTORY "${ANDROID_SDK}")
-    message(STATUS "Detected the android SDK directory at: " ${ANDROID_SDK}) 
+    message(STATUS "Detected the android SDK directory at: " ${ANDROID_SDK})
 else ()
     message(FATAL_ERROR "Couldn't detect the Android SDK directory")
 endif()
@@ -60,13 +60,13 @@
 if( NOT FPC_DIR)
     find_program(FPC_DIR ppcrossarm)
     get_filename_component(FPC_DIR "${FPC_DIR}" PATH)
-    if(IS_DIRECTORY "${FPC_DIR}") 
-    	set(FPC_DIR "${FPC_DIR}" CACHE PATH "Path to fpc dir used in the android port" FORCE)
+    if(IS_DIRECTORY "${FPC_DIR}")
+        set(FPC_DIR "${FPC_DIR}" CACHE PATH "Path to fpc dir used in the android port" FORCE)
     endif()
 endif()
 
 if( IS_DIRECTORY "${FPC_DIR}")
-    message(STATUS "Detected the FreePascal directory at: " "${FPC_DIR}") 
+    message(STATUS "Detected the FreePascal directory at: " "${FPC_DIR}")
 else ()
     message(FATAL_ERROR "Couldn't detect the FreePascal directory")
 endif()
--- a/project_files/frontlib/hwconsts.h	Sun Jun 09 12:20:19 2013 +0200
+++ b/project_files/frontlib/hwconsts.h	Sun Jun 09 12:22:53 2013 +0200
@@ -1,118 +1,118 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com>
- * Copyright (c) 2012 Simeon Maxein <smaxein@googlemail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-/**
- * This file contains important constants which might need to be changed to adapt to
- * changes in the engine or protocols.
- *
- * It also contains getter functions for some constants (in particular for constants
- * that are important for the layout of data structures), so that client code can
- * query the constants that the library was built with.
- */
-
-#ifndef HWCONSTS_H_
-#define HWCONSTS_H_
-
-#include <inttypes.h>
-#include <stddef.h>
-#include <stdbool.h>
-
-#define HEDGEHOGS_PER_TEAM 8
-#define DEFAULT_HEDGEHOG_COUNT 4
-#define DEFAULT_COLOR_INDEX 0
-
-#define NETGAME_DEFAULT_PORT 46631
-#define PROTOCOL_VERSION 42
-#define MIN_SERVER_VERSION 1
-
-//! Used for sending scripts to the engine
-#define MULTIPLAYER_SCRIPT_PATH "Scripts/Multiplayer/"
-
-#define WEAPONS_COUNT 56
-
-// TODO allow frontend to override these?
-/*! A merge of mikade/bugq colours w/ a bit of channel feedback */
-#define HW_TEAMCOLOR_ARRAY  { UINT32_C(0xffff0204), /*! red    */ \
-                              UINT32_C(0xff4980c1), /*! blue   */ \
-                              UINT32_C(0xff1de6ba), /*! teal   */ \
-                              UINT32_C(0xffb541ef), /*! purple */ \
-                              UINT32_C(0xffe55bb0), /*! pink   */ \
-                              UINT32_C(0xff20bf00), /*! green  */ \
-                              UINT32_C(0xfffe8b0e), /*! orange */ \
-                              UINT32_C(0xff5f3605), /*! brown  */ \
-                              UINT32_C(0xffffff01), /*! yellow */ \
-                              /*! add new colors here */ \
-                              0 } /*! Keep this 0 at the end */
-
-extern const size_t flib_teamcolor_count;
-extern const uint32_t flib_teamcolors[];
-
-/**
- * Returns the team color (ARGB) corresponding to the color index (0 if index out of bounds)
- */
-uint32_t flib_get_teamcolor(int colorIndex);
-
-/**
- * Returns the number of team colors (i.e. the length of the flib_teamcolors array)
- */
-int flib_get_teamcolor_count();
-
-/**
- * Returns the HEDGEHOGS_PER_TEAM constant
- */
-int flib_get_hedgehogs_per_team();
-
-/**
- * Returns the WEAPONS_COUNT constant
- */
-int flib_get_weapons_count();
-
-/*!
- * These structs define the meaning of values in the flib_scheme struct, i.e. their correspondence to
- * ini settings, engine commands and positions in the network protocol (the last is encoded in the
- * order of settings/mods).
- */
-typedef struct {
-    const char *name;				//!< A name identifying this setting (used as key in the schemes file)
-    const char *engineCommand;		//!< The command needed to send the setting to the engine. May be null if the setting is not sent to the engine (for the "health" setting)
-    const bool maxMeansInfinity;	//!< If true, send a very high number to the engine if the setting is equal to its maximum
-    const bool times1000;			//!< If true (for time-based settings), multiply the setting by 1000 before sending it to the engine.
-    const int min;					//!< The smallest allowed value
-    const int max;					//!< The highest allowed value
-    const int def;					//!< The default value
-} flib_metascheme_setting;
-
-typedef struct {
-    const char *name;				//!< A name identifying this mod (used as key in the schemes file)
-    const int bitmaskIndex;			//!< Mods are sent to the engine in a single integer, this field describes which bit of that integer is used
-    								//! for this particular mod.
-} flib_metascheme_mod;
-
-typedef struct {
-	const int settingCount;
-	const int modCount;
-	const flib_metascheme_setting *settings;
-	const flib_metascheme_mod *mods;
-} flib_metascheme;
-
-extern const flib_metascheme flib_meta;
-
-const flib_metascheme *flib_get_metascheme();
-
-#endif
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr@gmail.com>
+ * Copyright (c) 2012 Simeon Maxein <smaxein@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/**
+ * This file contains important constants which might need to be changed to adapt to
+ * changes in the engine or protocols.
+ *
+ * It also contains getter functions for some constants (in particular for constants
+ * that are important for the layout of data structures), so that client code can
+ * query the constants that the library was built with.
+ */
+
+#ifndef HWCONSTS_H_
+#define HWCONSTS_H_
+
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#define HEDGEHOGS_PER_TEAM 8
+#define DEFAULT_HEDGEHOG_COUNT 4
+#define DEFAULT_COLOR_INDEX 0
+
+#define NETGAME_DEFAULT_PORT 46631
+#define PROTOCOL_VERSION 42
+#define MIN_SERVER_VERSION 1
+
+//! Used for sending scripts to the engine
+#define MULTIPLAYER_SCRIPT_PATH "Scripts/Multiplayer/"
+
+#define WEAPONS_COUNT 56
+
+// TODO allow frontend to override these?
+/*! A merge of mikade/bugq colours w/ a bit of channel feedback */
+#define HW_TEAMCOLOR_ARRAY  { UINT32_C(0xffff0204), /*! red    */ \
+                              UINT32_C(0xff4980c1), /*! blue   */ \
+                              UINT32_C(0xff1de6ba), /*! teal   */ \
+                              UINT32_C(0xffb541ef), /*! purple */ \
+                              UINT32_C(0xffe55bb0), /*! pink   */ \
+                              UINT32_C(0xff20bf00), /*! green  */ \
+                              UINT32_C(0xfffe8b0e), /*! orange */ \
+                              UINT32_C(0xff5f3605), /*! brown  */ \
+                              UINT32_C(0xffffff01), /*! yellow */ \
+                              /*! add new colors here */ \
+                              0 } /*! Keep this 0 at the end */
+
+extern const size_t flib_teamcolor_count;
+extern const uint32_t flib_teamcolors[];
+
+/**
+ * Returns the team color (ARGB) corresponding to the color index (0 if index out of bounds)
+ */
+uint32_t flib_get_teamcolor(int colorIndex);
+
+/**
+ * Returns the number of team colors (i.e. the length of the flib_teamcolors array)
+ */
+int flib_get_teamcolor_count();
+
+/**
+ * Returns the HEDGEHOGS_PER_TEAM constant
+ */
+int flib_get_hedgehogs_per_team();
+
+/**
+ * Returns the WEAPONS_COUNT constant
+ */
+int flib_get_weapons_count();
+
+/*!
+ * These structs define the meaning of values in the flib_scheme struct, i.e. their correspondence to
+ * ini settings, engine commands and positions in the network protocol (the last is encoded in the
+ * order of settings/mods).
+ */
+typedef struct {
+    const char *name;               //!< A name identifying this setting (used as key in the schemes file)
+    const char *engineCommand;      //!< The command needed to send the setting to the engine. May be null if the setting is not sent to the engine (for the "health" setting)
+    const bool maxMeansInfinity;    //!< If true, send a very high number to the engine if the setting is equal to its maximum
+    const bool times1000;           //!< If true (for time-based settings), multiply the setting by 1000 before sending it to the engine.
+    const int min;                  //!< The smallest allowed value
+    const int max;                  //!< The highest allowed value
+    const int def;                  //!< The default value
+} flib_metascheme_setting;
+
+typedef struct {
+    const char *name;               //!< A name identifying this mod (used as key in the schemes file)
+    const int bitmaskIndex;         //!< Mods are sent to the engine in a single integer, this field describes which bit of that integer is used
+                                    //! for this particular mod.
+} flib_metascheme_mod;
+
+typedef struct {
+    const int settingCount;
+    const int modCount;
+    const flib_metascheme_setting *settings;
+    const flib_metascheme_mod *mods;
+} flib_metascheme;
+
+extern const flib_metascheme flib_meta;
+
+const flib_metascheme *flib_get_metascheme();
+
+#endif
--- a/project_files/frontlib/md5/md5.h	Sun Jun 09 12:20:19 2013 +0200
+++ b/project_files/frontlib/md5/md5.h	Sun Jun 09 12:22:53 2013 +0200
@@ -27,7 +27,7 @@
 
   This code implements the MD5 Algorithm defined in RFC 1321, whose
   text is available at
-	http://www.ietf.org/rfc/rfc1321.txt
+    http://www.ietf.org/rfc/rfc1321.txt
   The code is derived from the text of the RFC, including the test suite
   (section A.5) but excluding the rest of Appendix A.  It does not include
   any code or documentation that is identified in the RFC as being
@@ -38,12 +38,12 @@
   that follows (in reverse chronological order):
 
   2002-04-13 lpd Removed support for non-ANSI compilers; removed
-	references to Ghostscript; clarified derivation from RFC 1321;
-	now handles byte order either statically or dynamically.
+    references to Ghostscript; clarified derivation from RFC 1321;
+    now handles byte order either statically or dynamically.
   1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
   1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
-	added conditionalization for C++ compilation from Martin
-	Purschke <purschke@bnl.gov>.
+    added conditionalization for C++ compilation from Martin
+    Purschke <purschke@bnl.gov>.
   1999-05-03 lpd Original version.
  */
 
@@ -65,13 +65,13 @@
 
 /*! Define the state of the MD5 Algorithm. */
 typedef struct md5_state_s {
-    md5_word_t count[2];	/*! message length in bits, lsw first */
-    md5_word_t abcd[4];		/*! digest buffer */
-    md5_byte_t buf[64];		/*! accumulate block */
+    md5_word_t count[2];    /*! message length in bits, lsw first */
+    md5_word_t abcd[4];     /*! digest buffer */
+    md5_byte_t buf[64];     /*! accumulate block */
 } md5_state_t;
 
 #ifdef __cplusplus
-extern "C" 
+extern "C"
 {
 #endif
 
--- a/project_files/frontlib/model/gamesetup.h	Sun Jun 09 12:20:19 2013 +0200
+++ b/project_files/frontlib/model/gamesetup.h	Sun Jun 09 12:22:53 2013 +0200
@@ -1,47 +1,47 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-/**
- * A complete game configuration that contains all settings the engine needs to start a
- * local or networked game.
- */
-
-#ifndef MODEL_GAMESETUP_H_
-#define MODEL_GAMESETUP_H_
-
-#include "scheme.h"
-#include "weapon.h"
-#include "map.h"
-#include "teamlist.h"
-
-typedef struct {
-    char *style;				//!< e.g. "Capture the Flag"
-    flib_scheme *gamescheme;
-    flib_map *map;
-	flib_teamlist *teamlist;
-} flib_gamesetup;
-
-void flib_gamesetup_destroy(flib_gamesetup *gamesetup);
-
-/**
- * Deep-copy of the flib_gamesetup.
- */
-flib_gamesetup *flib_gamesetup_copy(const flib_gamesetup *gamesetup);
-
-#endif
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/**
+ * A complete game configuration that contains all settings the engine needs to start a
+ * local or networked game.
+ */
+
+#ifndef MODEL_GAMESETUP_H_
+#define MODEL_GAMESETUP_H_
+
+#include "scheme.h"
+#include "weapon.h"
+#include "map.h"
+#include "teamlist.h"
+
+typedef struct {
+    char *style;                //!< e.g. "Capture the Flag"
+    flib_scheme *gamescheme;
+    flib_map *map;
+    flib_teamlist *teamlist;
+} flib_gamesetup;
+
+void flib_gamesetup_destroy(flib_gamesetup *gamesetup);
+
+/**
+ * Deep-copy of the flib_gamesetup.
+ */
+flib_gamesetup *flib_gamesetup_copy(const flib_gamesetup *gamesetup);
+
+#endif
--- a/project_files/frontlib/model/map.h	Sun Jun 09 12:20:19 2013 +0200
+++ b/project_files/frontlib/model/map.h	Sun Jun 09 12:22:53 2013 +0200
@@ -1,114 +1,114 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-#ifndef MODEL_MAP_H_
-#define MODEL_MAP_H_
-
-#include <stddef.h>
-#include <stdint.h>
-#include <stdbool.h>
-
-#define MAPGEN_REGULAR 0
-#define MAPGEN_MAZE 1
-#define MAPGEN_DRAWN 2
-#define MAPGEN_NAMED 3
-
-#define TEMPLATEFILTER_ALL 0
-#define TEMPLATEFILTER_SMALL 1
-#define TEMPLATEFILTER_MEDIUM 2
-#define TEMPLATEFILTER_LARGE 3
-#define TEMPLATEFILTER_CAVERN 4
-#define TEMPLATEFILTER_WACKY 5
-
-#define MAZE_SIZE_SMALL_TUNNELS 0
-#define MAZE_SIZE_MEDIUM_TUNNELS 1
-#define MAZE_SIZE_LARGE_TUNNELS 2
-#define MAZE_SIZE_SMALL_ISLANDS 3
-#define MAZE_SIZE_MEDIUM_ISLANDS 4
-#define MAZE_SIZE_LARGE_ISLANDS 5
-
-/**
- * Data structure for defining a map. This contains the whole recipe to
- * exactly recreate a particular map.
- *
- * The required fields depend on the map generator, see the comments
- * at the struct for details.
- */
-typedef struct {
-	int mapgen;				//!< Always one of the MAPGEN_ constants
-	char *name;				//!< The name of the map for MAPGEN_NAMED (e.g. "Cogs"), otherwise one of "+rnd+", "+maze+" or "+drawn+".
-	char *seed;				//!< Used for all maps. This is a random seed for all (non-AI) entropy in the round. Typically a random UUID, but can be any string.
-	char *theme;			//!< Used for all maps. This is the name of a directory in Data/Themes (e.g. "Beach")
-	uint8_t *drawData;		//!< Used for MAPGEN_DRAWN
-	size_t drawDataSize;	//!< Used for MAPGEN_DRAWN
-	int templateFilter;		//!< Used for MAPGEN_REGULAR. One of the TEMPLATEFILTER_xxx constants.
-	int mazeSize;			//!< Used for MAPGEN_MAZE. One of the MAZE_SIZE_xxx constants.
-} flib_map;
-
-/**
- * Create a generated map. theme should be the name of a
- * directory in "Themes" and templateFilter should be one of the
- * TEMPLATEFILTER_* constants, but this is not checked before
- * passing it to the engine.
- *
- * Use flib_map_destroy to free the returned object.
- * No NULL parameters allowed, returns NULL on failure.
- */
-flib_map *flib_map_create_regular(const char *seed, const char *theme, int templateFilter);
-
-/**
- * Create a generated maze-type map. theme should be the name of a
- * directory in "Themes" and mazeSize should be one of the
- * MAZE_SIZE_* constants, but this is not checked before
- * passing it to the engine.
- *
- * Use flib_map_destroy to free the returned object.
- * No NULL parameters allowed, returns NULL on failure.
- */
-flib_map *flib_map_create_maze(const char *seed, const char *theme, int mazeSize);
-
-/**
- * Create a map from the Maps-Directory. name should be the name of a
- * directory in "Maps", but this is not checked before
- * passing it to the engine. If this is a mission, the corresponding
- * script is used automatically.
- *
- * Use flib_map_destroy to free the returned object.
- * No NULL parameters allowed, returns NULL on failure.
- */
-flib_map *flib_map_create_named(const char *seed, const char *name);
-
-/**
- * Create a hand-drawn map. Use flib_map_destroy to free the returned object.
- * No NULL parameters allowed, returns NULL on failure.
- */
-flib_map *flib_map_create_drawn(const char *seed, const char *theme, const uint8_t *drawData, size_t drawDataSize);
-
-/**
- * Create a deep copy of the map. Returns NULL on failure or if NULL was passed.
- */
-flib_map *flib_map_copy(const flib_map *map);
-
-/**
- * Decrease the reference count of the object and free it if this was the last reference.
- */
-void flib_map_destroy(flib_map *map);
-
-
-#endif
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef MODEL_MAP_H_
+#define MODEL_MAP_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#define MAPGEN_REGULAR 0
+#define MAPGEN_MAZE 1
+#define MAPGEN_DRAWN 2
+#define MAPGEN_NAMED 3
+
+#define TEMPLATEFILTER_ALL 0
+#define TEMPLATEFILTER_SMALL 1
+#define TEMPLATEFILTER_MEDIUM 2
+#define TEMPLATEFILTER_LARGE 3
+#define TEMPLATEFILTER_CAVERN 4
+#define TEMPLATEFILTER_WACKY 5
+
+#define MAZE_SIZE_SMALL_TUNNELS 0
+#define MAZE_SIZE_MEDIUM_TUNNELS 1
+#define MAZE_SIZE_LARGE_TUNNELS 2
+#define MAZE_SIZE_SMALL_ISLANDS 3
+#define MAZE_SIZE_MEDIUM_ISLANDS 4
+#define MAZE_SIZE_LARGE_ISLANDS 5
+
+/**
+ * Data structure for defining a map. This contains the whole recipe to
+ * exactly recreate a particular map.
+ *
+ * The required fields depend on the map generator, see the comments
+ * at the struct for details.
+ */
+typedef struct {
+    int mapgen;             //!< Always one of the MAPGEN_ constants
+    char *name;             //!< The name of the map for MAPGEN_NAMED (e.g. "Cogs"), otherwise one of "+rnd+", "+maze+" or "+drawn+".
+    char *seed;             //!< Used for all maps. This is a random seed for all (non-AI) entropy in the round. Typically a random UUID, but can be any string.
+    char *theme;            //!< Used for all maps. This is the name of a directory in Data/Themes (e.g. "Beach")
+    uint8_t *drawData;      //!< Used for MAPGEN_DRAWN
+    size_t drawDataSize;    //!< Used for MAPGEN_DRAWN
+    int templateFilter;     //!< Used for MAPGEN_REGULAR. One of the TEMPLATEFILTER_xxx constants.
+    int mazeSize;           //!< Used for MAPGEN_MAZE. One of the MAZE_SIZE_xxx constants.
+} flib_map;
+
+/**
+ * Create a generated map. theme should be the name of a
+ * directory in "Themes" and templateFilter should be one of the
+ * TEMPLATEFILTER_* constants, but this is not checked before
+ * passing it to the engine.
+ *
+ * Use flib_map_destroy to free the returned object.
+ * No NULL parameters allowed, returns NULL on failure.
+ */
+flib_map *flib_map_create_regular(const char *seed, const char *theme, int templateFilter);
+
+/**
+ * Create a generated maze-type map. theme should be the name of a
+ * directory in "Themes" and mazeSize should be one of the
+ * MAZE_SIZE_* constants, but this is not checked before
+ * passing it to the engine.
+ *
+ * Use flib_map_destroy to free the returned object.
+ * No NULL parameters allowed, returns NULL on failure.
+ */
+flib_map *flib_map_create_maze(const char *seed, const char *theme, int mazeSize);
+
+/**
+ * Create a map from the Maps-Directory. name should be the name of a
+ * directory in "Maps", but this is not checked before
+ * passing it to the engine. If this is a mission, the corresponding
+ * script is used automatically.
+ *
+ * Use flib_map_destroy to free the returned object.
+ * No NULL parameters allowed, returns NULL on failure.
+ */
+flib_map *flib_map_create_named(const char *seed, const char *name);
+
+/**
+ * Create a hand-drawn map. Use flib_map_destroy to free the returned object.
+ * No NULL parameters allowed, returns NULL on failure.
+ */
+flib_map *flib_map_create_drawn(const char *seed, const char *theme, const uint8_t *drawData, size_t drawDataSize);
+
+/**
+ * Create a deep copy of the map. Returns NULL on failure or if NULL was passed.
+ */
+flib_map *flib_map_copy(const flib_map *map);
+
+/**
+ * Decrease the reference count of the object and free it if this was the last reference.
+ */
+void flib_map_destroy(flib_map *map);
+
+
+#endif
--- a/project_files/frontlib/model/mapcfg.h	Sun Jun 09 12:20:19 2013 +0200
+++ b/project_files/frontlib/model/mapcfg.h	Sun Jun 09 12:22:53 2013 +0200
@@ -1,38 +1,38 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-/*!
- * Data structure and functions for accessing the map.cfg of named maps.
- */
-
-#ifndef MAPCFG_H_
-#define MAPCFG_H_
-
-typedef struct {
-	char theme[256];
-	int hogLimit;
-} flib_mapcfg;
-
-/**
- * Read the map configuration for the map with this name.
- * The dataDirPath must end in a path separator.
- */
-int flib_mapcfg_read(const char *dataDirPath, const char *mapname, flib_mapcfg *out);
-
-#endif /* MAPCFG_H_ */
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/*!
+ * Data structure and functions for accessing the map.cfg of named maps.
+ */
+
+#ifndef MAPCFG_H_
+#define MAPCFG_H_
+
+typedef struct {
+    char theme[256];
+    int hogLimit;
+} flib_mapcfg;
+
+/**
+ * Read the map configuration for the map with this name.
+ * The dataDirPath must end in a path separator.
+ */
+int flib_mapcfg_read(const char *dataDirPath, const char *mapname, flib_mapcfg *out);
+
+#endif /* MAPCFG_H_ */
--- a/project_files/frontlib/model/room.h	Sun Jun 09 12:20:19 2013 +0200
+++ b/project_files/frontlib/model/room.h	Sun Jun 09 12:22:53 2013 +0200
@@ -1,42 +1,42 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-/**
- * Models the room information for the lobby roomlist.
- */
-
-#ifndef ROOM_H_
-#define ROOM_H_
-
-#include <stdbool.h>
-
-typedef struct {
-    bool inProgress;	//!< true if the game is running
-    char *name;
-    int playerCount;
-    int teamCount;
-    char *owner;
-    char *map;			//!< This is either a map name, or one of +rnd+, +maze+ or +drawn+.
-    char *scheme;
-    char *weapons;
-} flib_room;
-
-void flib_room_destroy();
-
-#endif
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/**
+ * Models the room information for the lobby roomlist.
+ */
+
+#ifndef ROOM_H_
+#define ROOM_H_
+
+#include <stdbool.h>
+
+typedef struct {
+    bool inProgress;    //!< true if the game is running
+    char *name;
+    int playerCount;
+    int teamCount;
+    char *owner;
+    char *map;          //!< This is either a map name, or one of +rnd+, +maze+ or +drawn+.
+    char *scheme;
+    char *weapons;
+} flib_room;
+
+void flib_room_destroy();
+
+#endif
--- a/project_files/frontlib/model/team.h	Sun Jun 09 12:20:19 2013 +0200
+++ b/project_files/frontlib/model/team.h	Sun Jun 09 12:22:53 2013 +0200
@@ -1,130 +1,130 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-/**
- * This file defines a data structure for a hedgewars team.
- *
- * Teams are used in several different contexts in Hedgewars, and some of these require
- * extra information about teams. For example, the weaponset is important
- * to the engine, but not for ini reading/writing, and with the team statistics it is the
- * other way around. To keep things simple, the data structure can hold all information
- * used in any context. On the downside, that means we can't use static typing to ensure
- * that team information is "complete" for a particular purpose.
- */
-#ifndef TEAM_H_
-#define TEAM_H_
-
-
-#include "weapon.h"
-#include "../hwconsts.h"
-
-#include <stdbool.h>
-#include <stdint.h>
-
-#define TEAM_DEFAULT_HEALTH 100
-
-/**
- * Struct representing a single keybinding.
- */
-typedef struct {
-	char *action;
-	char *binding;
-} flib_binding;
-
-typedef struct {
-	char *name;
-	char *hat;			//!< e.g. hair_yellow; References a .png file in Data/Graphics/Hats
-
-	//! Statistics. They are irrelevant for the engine or server,
-	//! but provided for ini reading/writing by the frontend.
-	int rounds;
-	int kills;
-	int deaths;
-	int suicides;
-
-	int difficulty;		//!< 0 = human, 1 = most difficult bot ... 5 = least difficult bot (somewhat counterintuitive)
-
-	//! Transient setting used in game setup
-	int initialHealth;
-	flib_weaponset *weaponset;
-} flib_hog;
-
-typedef struct {
-	flib_hog hogs[HEDGEHOGS_PER_TEAM];
-	char *name;
-	char *grave;		//!< e.g. "Bone"; References a .png file in Data/Graphics/Graves
-	char *fort;			//!< e.g. "Castle"; References a series of files in Data/Forts
-	char *voicepack;	//!< e.g. "Classic"; References a directory in Data/Sounds/voices
-	char *flag;			//!< e.g. "hedgewars"; References a .png file in Data/Graphics/Flags
-
-	flib_binding *bindings;
-	int bindingCount;
-
-	//! Statistics. They are irrelevant for the engine or server,
-	//! but provided for ini reading/writing by the frontend.
-	int rounds;
-	int wins;
-	int campaignProgress;
-
-	//! Transient settings used in game setup
-	int colorIndex;		//!< Index into a color table
-	int hogsInGame;		//!< The number of hogs that will actually play
-	bool remoteDriven;	//!< true for non-local teams in a network game
-	char *ownerName;	//!< Username of the owner of a team in a network game
-} flib_team;
-
-/**
- * Free all memory associated with the team
- */
-void flib_team_destroy(flib_team *team);
-
-/**
- * Loads a team, returns NULL on error. Destroy this team using flib_team_destroy.
- * This will not fill in the fields marked as "transient" in the structs above.
- */
-flib_team *flib_team_from_ini(const char *filename);
-
-/**
- * Write the team to an ini file. Attempts to retain extra ini settings
- * that were already present. Note that not all fields of a team struct
- * are stored in the ini, some are only used intermittently to store
- * information about a team in the context of a game.
- *
- * The flib_team can handle "difficulty" on a per-hog basis, but it
- * is only written per-team in the team file. The difficulty of the
- * first hog is used for the entire team when writing.
- */
-int flib_team_to_ini(const char *filename, const flib_team *team);
-
-/**
- * Set the same weaponset for every hog in the team
- */
-int flib_team_set_weaponset(flib_team *team, const flib_weaponset *set);
-
-/**
- * Set the same initial health for every hog.
- */
-void flib_team_set_health(flib_team *team, int health);
-
-/**
- * Create a deep copy of a team. Returns NULL on failure.
- */
-flib_team *flib_team_copy(const flib_team *team);
-
-#endif /* TEAM_H_ */
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/**
+ * This file defines a data structure for a hedgewars team.
+ *
+ * Teams are used in several different contexts in Hedgewars, and some of these require
+ * extra information about teams. For example, the weaponset is important
+ * to the engine, but not for ini reading/writing, and with the team statistics it is the
+ * other way around. To keep things simple, the data structure can hold all information
+ * used in any context. On the downside, that means we can't use static typing to ensure
+ * that team information is "complete" for a particular purpose.
+ */
+#ifndef TEAM_H_
+#define TEAM_H_
+
+
+#include "weapon.h"
+#include "../hwconsts.h"
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#define TEAM_DEFAULT_HEALTH 100
+
+/**
+ * Struct representing a single keybinding.
+ */
+typedef struct {
+    char *action;
+    char *binding;
+} flib_binding;
+
+typedef struct {
+    char *name;
+    char *hat;          //!< e.g. hair_yellow; References a .png file in Data/Graphics/Hats
+
+    //! Statistics. They are irrelevant for the engine or server,
+    //! but provided for ini reading/writing by the frontend.
+    int rounds;
+    int kills;
+    int deaths;
+    int suicides;
+
+    int difficulty;     //!< 0 = human, 1 = most difficult bot ... 5 = least difficult bot (somewhat counterintuitive)
+
+    //! Transient setting used in game setup
+    int initialHealth;
+    flib_weaponset *weaponset;
+} flib_hog;
+
+typedef struct {
+    flib_hog hogs[HEDGEHOGS_PER_TEAM];
+    char *name;
+    char *grave;        //!< e.g. "Bone"; References a .png file in Data/Graphics/Graves
+    char *fort;         //!< e.g. "Castle"; References a series of files in Data/Forts
+    char *voicepack;    //!< e.g. "Classic"; References a directory in Data/Sounds/voices
+    char *flag;         //!< e.g. "hedgewars"; References a .png file in Data/Graphics/Flags
+
+    flib_binding *bindings;
+    int bindingCount;
+
+    //! Statistics. They are irrelevant for the engine or server,
+    //! but provided for ini reading/writing by the frontend.
+    int rounds;
+    int wins;
+    int campaignProgress;
+
+    //! Transient settings used in game setup
+    int colorIndex;     //!< Index into a color table
+    int hogsInGame;     //!< The number of hogs that will actually play
+    bool remoteDriven;  //!< true for non-local teams in a network game
+    char *ownerName;    //!< Username of the owner of a team in a network game
+} flib_team;
+
+/**
+ * Free all memory associated with the team
+ */
+void flib_team_destroy(flib_team *team);
+
+/**
+ * Loads a team, returns NULL on error. Destroy this team using flib_team_destroy.
+ * This will not fill in the fields marked as "transient" in the structs above.
+ */
+flib_team *flib_team_from_ini(const char *filename);
+
+/**
+ * Write the team to an ini file. Attempts to retain extra ini settings
+ * that were already present. Note that not all fields of a team struct
+ * are stored in the ini, some are only used intermittently to store
+ * information about a team in the context of a game.
+ *
+ * The flib_team can handle "difficulty" on a per-hog basis, but it
+ * is only written per-team in the team file. The difficulty of the
+ * first hog is used for the entire team when writing.
+ */
+int flib_team_to_ini(const char *filename, const flib_team *team);
+
+/**
+ * Set the same weaponset for every hog in the team
+ */
+int flib_team_set_weaponset(flib_team *team, const flib_weaponset *set);
+
+/**
+ * Set the same initial health for every hog.
+ */
+void flib_team_set_health(flib_team *team, int health);
+
+/**
+ * Create a deep copy of a team. Returns NULL on failure.
+ */
+flib_team *flib_team_copy(const flib_team *team);
+
+#endif /* TEAM_H_ */
--- a/project_files/frontlib/net/netconn.h	Sun Jun 09 12:20:19 2013 +0200
+++ b/project_files/frontlib/net/netconn.h	Sun Jun 09 12:22:53 2013 +0200
@@ -1,654 +1,654 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-/**
- * This file contains functions for communicating with a Hedgewars server to chat, prepare and play
- * rounds of Hedgewars.
- *
- * To use this, first create a netconn object by calling flib_netconn_create. This will start the
- * connection to the game server (which might fail right away, the function returns null then). You
- * should also register your callback functions right at the start to ensure you don't miss any
- * callbacks.
- *
- * In order to allow the netconn to run, you should regularly call flib_netconn_tick(), which
- * performs network I/O and calls your callbacks on interesting events.
- *
- * When the connection is closed, you will receive the onDisconnect callback. This is the signal to
- * destroy the netconn and stop calling tick().
- *
- * The connection process lasts from the time you create the netconn until you receive the
- * onConnected callback (or onDisconnected in case something goes wrong). During that time, you
- * might receive the onNickTaken and onPasswordRequest callbacks; see their description for more
- * information on how to handle them. You could also receive other callbacks during connecting (e.g.
- * about the room list), but it should be safe to ignore them.
- *
- * Once you are connected, you are in the lobby, and you can enter rooms and leave them again. The
- * room and lobby states have different protocols, so many commands only work in either one or the
- * other. If you are in a room you might also be in a game, but most of the functions behave the
- * same ingame as in a room.
- *
- * The state changes from lobby to room when the server tells you that you just entered one, which
- * will also trigger the onEnterRoom callback. This usually happens in reply to either a joinRoom,
- * createRoom or playerFollow command.
- *
- * The state changes back to lobby when the room is dissolved, when you are kicked from the room, or
- * when you actively leave the room using flib_netconn_send_leaveRoom. The first two events will
- * trigger the onLeaveRoom callback.
- */
-
-#ifndef NETCONN_H_
-#define NETCONN_H_
-
-#include "../model/gamesetup.h"
-#include "../model/scheme.h"
-#include "../model/room.h"
-
-#include <stddef.h>
-#include <stdint.h>
-#include <stdbool.h>
-
-#define NETCONN_STATE_CONNECTING 0
-#define NETCONN_STATE_LOBBY 1
-#define NETCONN_STATE_ROOM 2
-#define NETCONN_STATE_DISCONNECTED 10
-
-#define NETCONN_DISCONNECT_NORMAL 0				//!< The connection was closed normally
-#define NETCONN_DISCONNECT_SERVER_TOO_OLD 1		//!< The server has a lower protocol version than we do
-#define NETCONN_DISCONNECT_AUTH_FAILED 2		//!< You sent a password with flib_netconn_send_password that was not accepted
-#define NETCONN_DISCONNECT_CONNLOST 3			//!< The network connection was lost
-#define NETCONN_DISCONNECT_INTERNAL_ERROR 100	//!< Something went wrong in frontlib itself
-
-#define NETCONN_ROOMLEAVE_ABANDONED 0			//!< The room was closed because the chief left
-#define NETCONN_ROOMLEAVE_KICKED 1				//!< You have been kicked from the room
-
-#define NETCONN_MSG_TYPE_PLAYERINFO 0			//!< A response to flib_netconn_send_playerInfo
-#define NETCONN_MSG_TYPE_SERVERMESSAGE 1		//!< The welcome message when connecting to the lobby
-#define NETCONN_MSG_TYPE_WARNING 2				//!< A general warning message
-#define NETCONN_MSG_TYPE_ERROR 3				//!< A general error message
-
-#define NETCONN_MAPCHANGE_FULL 0
-#define NETCONN_MAPCHANGE_MAP 1
-#define NETCONN_MAPCHANGE_MAPGEN 2
-#define NETCONN_MAPCHANGE_DRAWNMAP 3
-#define NETCONN_MAPCHANGE_MAZE_SIZE 4
-#define NETCONN_MAPCHANGE_TEMPLATE 5
-#define NETCONN_MAPCHANGE_THEME 6
-#define NETCONN_MAPCHANGE_SEED 7
-
-typedef struct _flib_netconn flib_netconn;
-
-/**
- * Create a new netplay connection with these parameters.
- * The path to the data directory must end with a path delimiter (e.g. C:\Games\Hedgewars\Data\)
- */
-flib_netconn *flib_netconn_create(const char *playerName, const char *dataDirPath, const char *host, int port);
-void flib_netconn_destroy(flib_netconn *conn);
-
-/**
- * Perform I/O operations and call callbacks if something interesting happens.
- * Should be called regularly.
- */
-void flib_netconn_tick(flib_netconn *conn);
-
-/**
- * Are you currently the owner of this room? The return value only makes sense in
- * NETCONN_STATE_ROOM and NETCONN_STATE_INGAME states.
- */
-bool flib_netconn_is_chief(flib_netconn *conn);
-
-/**
- * Returns the playername. This is *probably* the one provided on creation, but if that name was
- * already taken, a different one could have been set by the onNickTaken callback or its default
- * implementation.
- */
-const char *flib_netconn_get_playername(flib_netconn *conn);
-
-/**
- * Generate a game setup from the current room state.
- * Returns NULL if the room state does not contain enough information for a complete game setup,
- * or if an error occurs.
- *
- * The new gamesetup must be destroyed with flib_gamesetup_destroy().
- */
-flib_gamesetup *flib_netconn_create_gamesetup(flib_netconn *conn);
-
-
-
-
-// Send functions needed when connecting and disconnecting
-
-	/**
-	 * Request a different nickname.
-	 * This function only makes sense in reaction to an onNickTaken callback, because the netconn
-	 * automatically requests the nickname you provide on creation, and once the server accepts the
-	 * nickname it can no longer be changed.
-	 */
-	int flib_netconn_send_nick(flib_netconn *conn, const char *nick);
-
-	/**
-	 * Send the password in reply to a password request.
-	 * If the server does not accept the password, you will be disconnected
-	 * (NETCONN_DISCONNECT_AUTH_FAILED)
-	 */
-	int flib_netconn_send_password(flib_netconn *conn, const char *passwd);
-
-	/**
-	 * Tell the server that you want to leave. If successful, the server will disconnect you.
-	 */
-	int flib_netconn_send_quit(flib_netconn *conn, const char *quitmsg);
-
-
-// Send functions that make sense both in the lobby and in rooms
-
-	/**
-	 * Send a chat message. This message is either sent to the lobby or the room, depending on
-	 * whether you are in a room at the moment. The message is not echoed back to you.
-	 */
-	int flib_netconn_send_chat(flib_netconn *conn, const char *chat);
-
-	/**
-	 * Kick a player. This has different meanings in the lobby and in a room;
-	 * In the lobby, it will kick the player from the server, and you need to be a server admin to
-	 * do it. In a room, it will kick the player from the room, and you need to be room chief.
-	 */
-	int flib_netconn_send_kick(flib_netconn *conn, const char *playerName);
-
-	/**
-	 * Request information about a player (e.g. current room, version, partial IP). If the action
-	 * succeeds, you will receive an onMessage callback with NETCONN_MSG_TYPE_PLAYERINFO containing
-	 * the requested information.
-	 */
-	int flib_netconn_send_playerInfo(flib_netconn *conn, const char *playerName);
-
-
-// Send functions that only make sense in the lobby
-
-	/**
-	 * Request an update of the room list. Only makes sense when in lobby state.
-	 * If the action succeeds, you will receive an onRoomlist callback containing the current room
-	 * data.
-	 */
-	int flib_netconn_send_request_roomlist(flib_netconn *conn);
-
-	/**
-	 * Join a room as guest (not chief). Only makes sense when in lobby state. If the action
-	 * succeeds, you will receive an onEnterRoom callback with chief=false followed by other
-	 * callbacks with current room information.
-	 */
-	int flib_netconn_send_joinRoom(flib_netconn *conn, const char *room);
-
-	/**
-	 * Follow a player. Only valid in the lobby. If the player is in a room (or in a game), this
-	 * command is analogous to calling flib_netconn_send_joinRoom with that room.
-	 */
-	int flib_netconn_send_playerFollow(flib_netconn *conn, const char *playerName);
-
-	/**
-	 * Create and join a new room. Only makes sense when in lobby state. If the action succeeds,
-	 * you will receive an onEnterRoom callback with chief=true.
-	 */
-	int flib_netconn_send_createRoom(flib_netconn *conn, const char *room);
-
-	/**
-	 * Ban a player. The scope of this ban depends on whether you are in a room or in the lobby.
-	 * In a room, you need to be the room chief, and the ban will apply to the room only. In the
-	 * lobby, you need to be server admin to ban someone, and the ban applies to the entire server.
-	 */
-	int flib_netconn_send_ban(flib_netconn *conn, const char *playerName);
-
-	/**
-	 * Does something administrator-y. At any rate you need to be an administrator and in the lobby
-	 * to use this command.
-	 */
-	int flib_netconn_send_clearAccountsCache(flib_netconn *conn);
-
-	/**
-	 * Sets a server variable to the indicated value. Only makes sense if you are server admin and
-	 * in the lobby. Known variables are MOTD_NEW, MOTD_OLD and LATEST_PROTO. MOTD_OLD is shown to
-	 * players with older protocol versions, to inform them that they might want to update.
-	 */
-	int flib_netconn_send_setServerVar(flib_netconn *conn, const char *name, const char *value);
-
-	/**
-	 * Queries all server variables. Only makes sense if you are server admin and in the lobby.
-	 * If the action succeeds, you will receive several onServerVar callbacks with the
-	 * current values of all server variables.
-	 */
-	int flib_netconn_send_getServerVars(flib_netconn *conn);
-
-
-// Send functions that only make sense in a room
-
-	/**
-	 * Leave the room for the lobby. Only makes sense in room state. msg can be NULL if you don't
-	 * want to send a message. The server always accepts a part command, so once you send it off,
-	 * you can just assume that you are back in the lobby.
-	 */
-	int flib_netconn_send_leaveRoom(flib_netconn *conn, const char *msg);
-
-	/**
-	 * Change your "ready" status in the room. Only makes sense when in room state. If the action
-	 * succeeds, you will receive an onClientFlags callback containing the change.
-	 */
-	int flib_netconn_send_toggleReady(flib_netconn *conn);
-
-	/**
-	 * Add a team to the current room. Apart from the "fixed" team information, this also includes
-	 * the color, but not the number of hogs. Only makes sense when in room state. If the action
-	 * succeeds, you will receive an onTeamAccepted callback with the name of the team.
-	 *
-	 * Notes: Technically, sending a color here is the only way for a non-chief to set the color of
-	 * her own team. The server remembers this color and even generates a separate teamColor message
-	 * to inform everyone of it. However, at the moment the frontends generally override this color
-	 * with one they choose themselves in order to deal with unfortunate behavior of the QtFrontend,
-	 * which always sends color index 0 when adding a team but thinks that the team has a random
-	 * color. The chief always sends a new color in order to bring the QtFrontend back into sync.
-	 */
-	int flib_netconn_send_addTeam(flib_netconn *conn, const flib_team *team);
-
-	/**
-	 * Remove the team with the name teamname. Only makes sense when in room state.
-	 * The server does not send a reply on success.
-	 */
-	int flib_netconn_send_removeTeam(flib_netconn *conn, const char *teamname);
-
-
-// Send functions that only make sense in a room and if you are room chief
-
-	/**
-	 * Rename the current room. Only makes sense in room state and if you are chief. If the action
-	 * succeeds, you (and everyone else on the server) will receive an onRoomUpdate message
-	 * containing the change.
-	 */
-	int flib_netconn_send_renameRoom(flib_netconn *conn, const char *roomName);
-
-	/**
-	 * Set the number of hogs for a team. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_teamHogCount(flib_netconn *conn, const char *teamname, int hogcount);
-
-	/**
-	 * Set the teamcolor of a team. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_teamColor(flib_netconn *conn, const char *teamname, int colorIndex);
-
-	/**
-	 * Set the weaponset for the room. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_weaponset(flib_netconn *conn, const flib_weaponset *weaponset);
-
-	/**
-	 * Set the map for the room. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_map(flib_netconn *conn, const flib_map *map);
-
-	/**
-	 * Set the mapname. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_mapName(flib_netconn *conn, const char *mapName);
-
-	/**
-	 * Set the map generator (regular, maze, drawn, named). Only makes sense in room state and if
-	 * you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_mapGen(flib_netconn *conn, int mapGen);
-
-	/**
-	 * Set the map template for regular maps. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_mapTemplate(flib_netconn *conn, int templateFilter);
-
-	/**
-	 * Set the maze template (maze size) for mazes. Only makes sense in room state and if you are
-	 * chief. The server does not send a reply.
-	 */
-	int flib_netconn_send_mapMazeSize(flib_netconn *conn, int mazeSize);
-
-	/**
-	 * Set the seed for the map. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_mapSeed(flib_netconn *conn, const char *seed);
-
-	/**
-	 * Set the theme for the map. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_mapTheme(flib_netconn *conn, const char *theme);
-
-	/**
-	 * Set the draw data for the drawn map. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_mapDrawdata(flib_netconn *conn, const uint8_t *drawData, size_t size);
-
-	/**
-	 * Set the script (game style). Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_script(flib_netconn *conn, const char *scriptName);
-
-	/**
-	 * Set the scheme. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_scheme(flib_netconn *conn, const flib_scheme *scheme);
-
-	/**
-	 * Signal that you want to start the game. Only makes sense in room state and if you are chief.
-	 * The server will check whether all players are ready and whether it believes the setup makes
-	 * sense (e.g. more than one clan). If the server is satisfied, you will receive an onRunGame
-	 * callback (all other clients in the room are notified the same way). Otherwise the server
-	 * might answer with a warning, or might not answer at all.
-	 */
-	int flib_netconn_send_startGame(flib_netconn *conn);
-
-	/**
-	 * Allow/forbid players to join the room. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_toggleRestrictJoins(flib_netconn *conn);
-
-	/**
-	 * Allow/forbid adding teams to the room. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_toggleRestrictTeams(flib_netconn *conn);
-
-
-// Send functions that are only needed for running a game
-
-	/**
-	 * Send a teamchat message, forwarded from the engine. Only makes sense ingame.
-	 * The server does not send a reply. In contrast to a Chat message, the server
-	 * automatically converts this into an engine message and passes it on to the other
-	 * clients.
-	 */
-	int flib_netconn_send_teamchat(flib_netconn *conn, const char *msg);
-
-	/**
-	 * Send an engine message. Only makes sense when ingame. In a networked game, you have to pass
-	 * all the engine messages from the engine here, and they will be spread to all other clients
-	 * in the game to keep the game in sync.
-	 */
-	int flib_netconn_send_engineMessage(flib_netconn *conn, const uint8_t *message, size_t size);
-
-	/**
-	 * Inform the server that the round has ended. Call this when the engine has disconnected,
-	 * passing 1 if the round ended normally, 0 otherwise.
-	 */
-	int flib_netconn_send_roundfinished(flib_netconn *conn, bool withoutError);
-
-
-
-
-
-// Callbacks that are important for connecting/disconnecting
-
-	/**
-	 * onNickTaken is called when connecting to the server, if it turns out that there is already a
-	 * player with the same nick.
-	 * In order to proceed, a new nickname needs to be sent to the server using
-	 * flib_netconn_send_nick() (or of course you can bail out and send a QUIT).
-	 * If you don't set a callback, the netconn will automatically react by generating a new name.
-	 */
-	void flib_netconn_onNickTaken(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context);
-
-	/**
-	 * When connecting with a registered nickname, the server will ask for a password before
-	 * admitting you in. This callback is called when that happens. As a reaction, you can send the
-	 * password using flib_netconn_send_password. If you don't register a callback, the default
-	 * behavior is to just quit in a way that will cause a disconnect with
-	 * NETCONN_DISCONNECT_AUTH_FAILED.
-	 *
-	 * You can't just choose a new nickname when you receive this callback, because at that point
-	 * the server has already accepted your nick.
-	 */
-	void flib_netconn_onPasswordRequest(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context);
-
-	/**
-	 * This is called when the server has accepted our nickname (and possibly password) and we have
-	 * entered the lobby.
-	 */
-	void flib_netconn_onConnected(flib_netconn *conn, void (*callback)(void *context), void* context);
-
-	/**
-	 * This is always the last callback (unless the netconn is destroyed early), and the netconn
-	 * should be destroyed when it is received. The reason for the disconnect is passed as one of
-	 * the NETCONN_DISCONNECT_ constants. Sometimes a message is included as well, but that
-	 * parameter might also be NULL.
-	 */
-	void flib_netconn_onDisconnected(flib_netconn *conn, void (*callback)(void *context, int reason, const char *message), void* context);
-
-
-// Callbacks that make sense in most situations
-
-	/**
-	 * Callback for several informational messages that should be displayed to the user
-	 * (e.g. in the chat window), but do not require a reaction. If a game is running, you might
-	 * want to redirect some of these messages to the engine as well so the user will see them.
-	 */
-	void flib_netconn_onMessage(flib_netconn *conn, void (*callback)(void *context, int msgtype, const char *msg), void* context);
-
-	/**
-	 * We received a chat message. Where this message belongs depends on the current state
-	 * (lobby/room). If a game is running the message should be passed to the engine.
-	 */
-	void flib_netconn_onChat(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *msg), void* context);
-
-	/**
-	 * Callbacks for incremental room list updates. They will fire whenever these events occur,
-	 * even before you first query the actual roomlist - so be sure not to blindly reference your
-	 * room list in these callbacks. The server currently only sends updates when a room changes
-	 * its name, so in order to update other room information you need to query the roomlist again
-	 * (see send_request_roomlist / onRoomlist).
-	 */
-	void flib_netconn_onRoomAdd(flib_netconn *conn, void (*callback)(void *context, const flib_room *room), void* context);
-	void flib_netconn_onRoomDelete(flib_netconn *conn, void (*callback)(void *context, const char *name), void* context);
-	void flib_netconn_onRoomUpdate(flib_netconn *conn, void (*callback)(void *context, const char *oldName, const flib_room *room), void* context);
-
-	/**
-	 * Callbacks for players joining or leaving the lobby. In contrast to the roomlist updates, you
-	 * will get a JOIN callback for every player already on the server when you join (and there is
-	 * no direct way to query the current playerlist)
-	 *
-	 * NOTE: partMessage may be NULL.
-	 */
-	void flib_netconn_onLobbyJoin(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context);
-	void flib_netconn_onLobbyLeave(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *partMessage), void* context);
-
-	/**
-	 * This is called when the server informs us that one or more flags associated with a
-	 * player/client have changed.
-	 *
-	 * nick is the name of the player, flags is a string containing one character for each modified
-	 * flag (see below), and newFlagState signals whether the flags should be set to true or false.
-	 *
-	 * Some of these flags are important for protocol purposes (especially if they are set for you)
-	 * while others are just informational. Also, some flags are only relevant for players who are
-	 * in the same room as you, and the server will not inform you if they change for others.
-	 *
-	 * These are the currently known/used flags:
-	 * a: Server admin. Always updated.
-	 * h: Room chief. Updated when in the same room.
-	 * r: Ready to play. Updated when in the same room.
-	 * u: Registered user. Always updated.
-	 *
-	 * The server tells us the 'a' and 'u' flags for all players when we first join the lobby, and
-	 * also tells us the 'r' and 'h' flags when we join or create a room. It assumes that all flags
-	 * are initially false, so it will typically only tell you to set certain flags to true when
-	 * transmitting the initial states. Reset the 'h' and 'r' flags to false when leaving a room,
-	 * or when entering room state, to arrive at the right state for each player.
-	 *
-	 * The room chief state of yourself is particularly important because it determines whether you
-	 * can modify settings of the current room. Generally, when you create a room you start out
-	 * being room chief, and when you join an existing room you are not. However, if the original
-	 * chief leaves a room, the server can choose a new chief, and if that happens the chief flag
-	 * will be transferred to someone else.
-	 */
-	void flib_netconn_onClientFlags(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *flags, bool newFlagState), void *context);
-
-// Callbacks that happen only in response to specific requests
-
-	/**
-	 * Response to flib_netconn_send_request_roomlist().
-	 * The rooms array contains the current state of all rooms on the server.
-	 */
-	void flib_netconn_onRoomlist(flib_netconn *conn, void (*callback)(void *context, const flib_room **rooms, int roomCount), void* context);
-
-	/**
-	 * Response to flib_netconn_send_joinRoom, flib_netconn_send_playerFollow or
-	 * flib_netconn_send_createRoom.
-	 *
-	 * You just left the lobby and entered a room.
-	 * If chief is true, you can and should send a full configuration for the room now. This
-	 * consists of ammo, scheme, script and map, where map apparently has to come last.
-	 */
-	void flib_netconn_onEnterRoom(flib_netconn *conn, void (*callback)(void *context, bool chief), void *context);
-
-	/**
-	 * Response to flib_netconn_send_addTeam.
-	 * The server might reject your team for several reasons, e.g. because it has the same name as
-	 * an existing team, or because the room chief restricted adding new teams. If the team is
-	 * accepted by the server, this callback is fired.
-	 *
-	 * If you are the room chief, you are expected to provide the hog count for your own team now
-	 * using flib_netconn_send_teamHogCount. The color of the team is already set to the one you
-	 * provided in addTeam.
-	 */
-	void flib_netconn_onTeamAccepted(flib_netconn *conn, void (*callback)(void *context, const char *team), void *context);
-
-	/**
-	 * When you query the server vars with flib_netconn_send_getServerVars (only works as admin),
-	 * the server replies with a list of them. This callback is called for each entry in that list.
-	 */
-	void flib_netconn_onServerVar(flib_netconn *conn, void (*callback)(void *context, const char *name, const char *value), void *context);
-
-
-// Callbacks that are only relevant in a room
-
-	/**
-	 * You just left a room and entered the lobby again.
-	 * reason is one of the NETCONN_ROOMLEAVE_ constants (usually a kick).
-	 * This will not be called when you actively leave a room using PART.
-	 * Don't confuse with onRoomLeave, which indicates that *someone else* left the room.
-	 */
-	void flib_netconn_onLeaveRoom(flib_netconn *conn, void (*callback)(void *context, int reason, const char *message), void *context);
-
-	/**
-	 * Someone joined or left the room you are currently in.
-	 * Analogous to onLobbyJoin/leave, you will receive the join callback for all players that are
-	 * already in the room when you join, including for yourself (this is actually how it is
-	 * determined that you joined a room).
-	 *
-	 * However, you will *not* receive onRoomLeave messages for everyone when you leave the room.
-	 */
-	void flib_netconn_onRoomJoin(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context);
-	void flib_netconn_onRoomLeave(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *partMessage), void* context);
-
-	/**
-	 * A new team was added to the room. The person who adds a team does NOT receive this callback
-	 * (he gets onTeamAccepted instead).
-	 *
-	 * The team does not contain bindings, stats, weaponset, color or the number of hogs (but it is
-	 * assumed to be the default of 4).
-	 *
-	 * If you receive this message and you are the room chief, you may want to send a color and hog
-	 * count for this team using flib_netconn_send_teamHogCount / teamColor for QtFrontend
-	 * compatibility.
-	 *
-	 * The server currently sends another message with the color of the team to the same recipients
-	 * as this teamAdd message, which will trigger an onTeamColorChanged callback. See the
-	 * description of flib_netconn_send_addTeam for more information.
-	 */
-	void flib_netconn_onTeamAdd(flib_netconn *conn, void (*callback)(void *context, const flib_team *team), void *context);
-
-	/**
-	 * A team was removed from the room. The person who removed the team will not receive this
-	 * callback.
-	 */
-	void flib_netconn_onTeamDelete(flib_netconn *conn, void (*callback)(void *context, const char *teamname), void *context);
-
-	/**
-	 * The number of hogs in a team has been changed by the room chief. If you are the chief and
-	 * change the number of hogs yourself, you will not receive this callback.
-	 */
-	void flib_netconn_onHogCountChanged(flib_netconn *conn, void (*callback)(void *context, const char *teamName, int hogs), void *context);
-
-	/**
-	 * The color of a team has been set or changed. The client who set or changed the color will
-	 * not receive this callback.
-	 *
-	 * Normally, only the chief can change the color of a team. However, this message is also
-	 * generated when a team is added, so you can receive it even as chief.
-	 */
-	void flib_netconn_onTeamColorChanged(flib_netconn *conn, void (*callback)(void *context, const char *teamName, int colorIndex), void *context);
-
-	/**
-	 * The room chief has changed the game scheme (or you just joined a room).
-	 * You will not receive this callback if you changed the scheme yourself.
-	 */
-	void flib_netconn_onSchemeChanged(flib_netconn *conn, void (*callback)(void *context, const flib_scheme *scheme), void *context);
-
-	/**
-	 * The room chief has changed the map (or you just joined a room). Only non-chiefs receive these
-	 * messages.
-	 *
-	 * To reduce the number of callback functions, the netconn keeps track of the current map
-	 * settings and always passes the entire current map config, but informs the callee about what
-	 * has changed (see the NETCONN_MAPCHANGE_ constants).
-	 *
-	 * Caution: Due to the way the protocol works, the map might not be complete at this point if it
-	 * is a hand-drawn map, because the "full" map config does not include the drawn map data.
-	 */
-	void flib_netconn_onMapChanged(flib_netconn *conn, void (*callback)(void *context, const flib_map *map, int changetype), void *context);
-
-	/**
-	 * The room chief has changed the game style (or you just joined a room). If you are the chief
-	 * and change the style yourself, you will not receive this callback.
-	 */
-	void flib_netconn_onScriptChanged(flib_netconn *conn, void (*callback)(void *context, const char *script), void *context);
-
-	/**
-	 * The room chief has changed the weaponset (or you just joined a room). If you are the chief
-	 * and change the weaponset yourself, you will not receive this callback.
-	 */
-	void flib_netconn_onWeaponsetChanged(flib_netconn *conn, void (*callback)(void *context, const flib_weaponset *weaponset), void *context);
-
-	/**
-	 * The game is starting. Fire up the engine and join in!
-	 * You can let the netconn generate the right game setup using flib_netconn_create_gamesetup
-	 */
-	void flib_netconn_onRunGame(flib_netconn *conn, void (*callback)(void *context), void *context);
-
-	/**
-	 * You are in a room, a game is in progress, and the server is sending you the new input for the
-	 * engine to keep up to date with the current happenings. Pass it on to the engine using
-	 * flib_gameconn_send_enginemsg.
-	 */
-	void flib_netconn_onEngineMessage(flib_netconn *conn, void (*callback)(void *context, const uint8_t *message, size_t size), void *context);
-
-#endif
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/**
+ * This file contains functions for communicating with a Hedgewars server to chat, prepare and play
+ * rounds of Hedgewars.
+ *
+ * To use this, first create a netconn object by calling flib_netconn_create. This will start the
+ * connection to the game server (which might fail right away, the function returns null then). You
+ * should also register your callback functions right at the start to ensure you don't miss any
+ * callbacks.
+ *
+ * In order to allow the netconn to run, you should regularly call flib_netconn_tick(), which
+ * performs network I/O and calls your callbacks on interesting events.
+ *
+ * When the connection is closed, you will receive the onDisconnect callback. This is the signal to
+ * destroy the netconn and stop calling tick().
+ *
+ * The connection process lasts from the time you create the netconn until you receive the
+ * onConnected callback (or onDisconnected in case something goes wrong). During that time, you
+ * might receive the onNickTaken and onPasswordRequest callbacks; see their description for more
+ * information on how to handle them. You could also receive other callbacks during connecting (e.g.
+ * about the room list), but it should be safe to ignore them.
+ *
+ * Once you are connected, you are in the lobby, and you can enter rooms and leave them again. The
+ * room and lobby states have different protocols, so many commands only work in either one or the
+ * other. If you are in a room you might also be in a game, but most of the functions behave the
+ * same ingame as in a room.
+ *
+ * The state changes from lobby to room when the server tells you that you just entered one, which
+ * will also trigger the onEnterRoom callback. This usually happens in reply to either a joinRoom,
+ * createRoom or playerFollow command.
+ *
+ * The state changes back to lobby when the room is dissolved, when you are kicked from the room, or
+ * when you actively leave the room using flib_netconn_send_leaveRoom. The first two events will
+ * trigger the onLeaveRoom callback.
+ */
+
+#ifndef NETCONN_H_
+#define NETCONN_H_
+
+#include "../model/gamesetup.h"
+#include "../model/scheme.h"
+#include "../model/room.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#define NETCONN_STATE_CONNECTING 0
+#define NETCONN_STATE_LOBBY 1
+#define NETCONN_STATE_ROOM 2
+#define NETCONN_STATE_DISCONNECTED 10
+
+#define NETCONN_DISCONNECT_NORMAL 0             //!< The connection was closed normally
+#define NETCONN_DISCONNECT_SERVER_TOO_OLD 1     //!< The server has a lower protocol version than we do
+#define NETCONN_DISCONNECT_AUTH_FAILED 2        //!< You sent a password with flib_netconn_send_password that was not accepted
+#define NETCONN_DISCONNECT_CONNLOST 3           //!< The network connection was lost
+#define NETCONN_DISCONNECT_INTERNAL_ERROR 100   //!< Something went wrong in frontlib itself
+
+#define NETCONN_ROOMLEAVE_ABANDONED 0           //!< The room was closed because the chief left
+#define NETCONN_ROOMLEAVE_KICKED 1              //!< You have been kicked from the room
+
+#define NETCONN_MSG_TYPE_PLAYERINFO 0           //!< A response to flib_netconn_send_playerInfo
+#define NETCONN_MSG_TYPE_SERVERMESSAGE 1        //!< The welcome message when connecting to the lobby
+#define NETCONN_MSG_TYPE_WARNING 2              //!< A general warning message
+#define NETCONN_MSG_TYPE_ERROR 3                //!< A general error message
+
+#define NETCONN_MAPCHANGE_FULL 0
+#define NETCONN_MAPCHANGE_MAP 1
+#define NETCONN_MAPCHANGE_MAPGEN 2
+#define NETCONN_MAPCHANGE_DRAWNMAP 3
+#define NETCONN_MAPCHANGE_MAZE_SIZE 4
+#define NETCONN_MAPCHANGE_TEMPLATE 5
+#define NETCONN_MAPCHANGE_THEME 6
+#define NETCONN_MAPCHANGE_SEED 7
+
+typedef struct _flib_netconn flib_netconn;
+
+/**
+ * Create a new netplay connection with these parameters.
+ * The path to the data directory must end with a path delimiter (e.g. C:\Games\Hedgewars\Data\)
+ */
+flib_netconn *flib_netconn_create(const char *playerName, const char *dataDirPath, const char *host, int port);
+void flib_netconn_destroy(flib_netconn *conn);
+
+/**
+ * Perform I/O operations and call callbacks if something interesting happens.
+ * Should be called regularly.
+ */
+void flib_netconn_tick(flib_netconn *conn);
+
+/**
+ * Are you currently the owner of this room? The return value only makes sense in
+ * NETCONN_STATE_ROOM and NETCONN_STATE_INGAME states.
+ */
+bool flib_netconn_is_chief(flib_netconn *conn);
+
+/**
+ * Returns the playername. This is *probably* the one provided on creation, but if that name was
+ * already taken, a different one could have been set by the onNickTaken callback or its default
+ * implementation.
+ */
+const char *flib_netconn_get_playername(flib_netconn *conn);
+
+/**
+ * Generate a game setup from the current room state.
+ * Returns NULL if the room state does not contain enough information for a complete game setup,
+ * or if an error occurs.
+ *
+ * The new gamesetup must be destroyed with flib_gamesetup_destroy().
+ */
+flib_gamesetup *flib_netconn_create_gamesetup(flib_netconn *conn);
+
+
+
+
+// Send functions needed when connecting and disconnecting
+
+    /**
+     * Request a different nickname.
+     * This function only makes sense in reaction to an onNickTaken callback, because the netconn
+     * automatically requests the nickname you provide on creation, and once the server accepts the
+     * nickname it can no longer be changed.
+     */
+    int flib_netconn_send_nick(flib_netconn *conn, const char *nick);
+
+    /**
+     * Send the password in reply to a password request.
+     * If the server does not accept the password, you will be disconnected
+     * (NETCONN_DISCONNECT_AUTH_FAILED)
+     */
+    int flib_netconn_send_password(flib_netconn *conn, const char *passwd);
+
+    /**
+     * Tell the server that you want to leave. If successful, the server will disconnect you.
+     */
+    int flib_netconn_send_quit(flib_netconn *conn, const char *quitmsg);
+
+
+// Send functions that make sense both in the lobby and in rooms
+
+    /**
+     * Send a chat message. This message is either sent to the lobby or the room, depending on
+     * whether you are in a room at the moment. The message is not echoed back to you.
+     */
+    int flib_netconn_send_chat(flib_netconn *conn, const char *chat);
+
+    /**
+     * Kick a player. This has different meanings in the lobby and in a room;
+     * In the lobby, it will kick the player from the server, and you need to be a server admin to
+     * do it. In a room, it will kick the player from the room, and you need to be room chief.
+     */
+    int flib_netconn_send_kick(flib_netconn *conn, const char *playerName);
+
+    /**
+     * Request information about a player (e.g. current room, version, partial IP). If the action
+     * succeeds, you will receive an onMessage callback with NETCONN_MSG_TYPE_PLAYERINFO containing
+     * the requested information.
+     */
+    int flib_netconn_send_playerInfo(flib_netconn *conn, const char *playerName);
+
+
+// Send functions that only make sense in the lobby
+
+    /**
+     * Request an update of the room list. Only makes sense when in lobby state.
+     * If the action succeeds, you will receive an onRoomlist callback containing the current room
+     * data.
+     */
+    int flib_netconn_send_request_roomlist(flib_netconn *conn);
+
+    /**
+     * Join a room as guest (not chief). Only makes sense when in lobby state. If the action
+     * succeeds, you will receive an onEnterRoom callback with chief=false followed by other
+     * callbacks with current room information.
+     */
+    int flib_netconn_send_joinRoom(flib_netconn *conn, const char *room);
+
+    /**
+     * Follow a player. Only valid in the lobby. If the player is in a room (or in a game), this
+     * command is analogous to calling flib_netconn_send_joinRoom with that room.
+     */
+    int flib_netconn_send_playerFollow(flib_netconn *conn, const char *playerName);
+
+    /**
+     * Create and join a new room. Only makes sense when in lobby state. If the action succeeds,
+     * you will receive an onEnterRoom callback with chief=true.
+     */
+    int flib_netconn_send_createRoom(flib_netconn *conn, const char *room);
+
+    /**
+     * Ban a player. The scope of this ban depends on whether you are in a room or in the lobby.
+     * In a room, you need to be the room chief, and the ban will apply to the room only. In the
+     * lobby, you need to be server admin to ban someone, and the ban applies to the entire server.
+     */
+    int flib_netconn_send_ban(flib_netconn *conn, const char *playerName);
+
+    /**
+     * Does something administrator-y. At any rate you need to be an administrator and in the lobby
+     * to use this command.
+     */
+    int flib_netconn_send_clearAccountsCache(flib_netconn *conn);
+
+    /**
+     * Sets a server variable to the indicated value. Only makes sense if you are server admin and
+     * in the lobby. Known variables are MOTD_NEW, MOTD_OLD and LATEST_PROTO. MOTD_OLD is shown to
+     * players with older protocol versions, to inform them that they might want to update.
+     */
+    int flib_netconn_send_setServerVar(flib_netconn *conn, const char *name, const char *value);
+
+    /**
+     * Queries all server variables. Only makes sense if you are server admin and in the lobby.
+     * If the action succeeds, you will receive several onServerVar callbacks with the
+     * current values of all server variables.
+     */
+    int flib_netconn_send_getServerVars(flib_netconn *conn);
+
+
+// Send functions that only make sense in a room
+
+    /**
+     * Leave the room for the lobby. Only makes sense in room state. msg can be NULL if you don't
+     * want to send a message. The server always accepts a part command, so once you send it off,
+     * you can just assume that you are back in the lobby.
+     */
+    int flib_netconn_send_leaveRoom(flib_netconn *conn, const char *msg);
+
+    /**
+     * Change your "ready" status in the room. Only makes sense when in room state. If the action
+     * succeeds, you will receive an onClientFlags callback containing the change.
+     */
+    int flib_netconn_send_toggleReady(flib_netconn *conn);
+
+    /**
+     * Add a team to the current room. Apart from the "fixed" team information, this also includes
+     * the color, but not the number of hogs. Only makes sense when in room state. If the action
+     * succeeds, you will receive an onTeamAccepted callback with the name of the team.
+     *
+     * Notes: Technically, sending a color here is the only way for a non-chief to set the color of
+     * her own team. The server remembers this color and even generates a separate teamColor message
+     * to inform everyone of it. However, at the moment the frontends generally override this color
+     * with one they choose themselves in order to deal with unfortunate behavior of the QtFrontend,
+     * which always sends color index 0 when adding a team but thinks that the team has a random
+     * color. The chief always sends a new color in order to bring the QtFrontend back into sync.
+     */
+    int flib_netconn_send_addTeam(flib_netconn *conn, const flib_team *team);
+
+    /**
+     * Remove the team with the name teamname. Only makes sense when in room state.
+     * The server does not send a reply on success.
+     */
+    int flib_netconn_send_removeTeam(flib_netconn *conn, const char *teamname);
+
+
+// Send functions that only make sense in a room and if you are room chief
+
+    /**
+     * Rename the current room. Only makes sense in room state and if you are chief. If the action
+     * succeeds, you (and everyone else on the server) will receive an onRoomUpdate message
+     * containing the change.
+     */
+    int flib_netconn_send_renameRoom(flib_netconn *conn, const char *roomName);
+
+    /**
+     * Set the number of hogs for a team. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_teamHogCount(flib_netconn *conn, const char *teamname, int hogcount);
+
+    /**
+     * Set the teamcolor of a team. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_teamColor(flib_netconn *conn, const char *teamname, int colorIndex);
+
+    /**
+     * Set the weaponset for the room. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_weaponset(flib_netconn *conn, const flib_weaponset *weaponset);
+
+    /**
+     * Set the map for the room. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_map(flib_netconn *conn, const flib_map *map);
+
+    /**
+     * Set the mapname. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_mapName(flib_netconn *conn, const char *mapName);
+
+    /**
+     * Set the map generator (regular, maze, drawn, named). Only makes sense in room state and if
+     * you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_mapGen(flib_netconn *conn, int mapGen);
+
+    /**
+     * Set the map template for regular maps. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_mapTemplate(flib_netconn *conn, int templateFilter);
+
+    /**
+     * Set the maze template (maze size) for mazes. Only makes sense in room state and if you are
+     * chief. The server does not send a reply.
+     */
+    int flib_netconn_send_mapMazeSize(flib_netconn *conn, int mazeSize);
+
+    /**
+     * Set the seed for the map. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_mapSeed(flib_netconn *conn, const char *seed);
+
+    /**
+     * Set the theme for the map. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_mapTheme(flib_netconn *conn, const char *theme);
+
+    /**
+     * Set the draw data for the drawn map. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_mapDrawdata(flib_netconn *conn, const uint8_t *drawData, size_t size);
+
+    /**
+     * Set the script (game style). Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_script(flib_netconn *conn, const char *scriptName);
+
+    /**
+     * Set the scheme. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_scheme(flib_netconn *conn, const flib_scheme *scheme);
+
+    /**
+     * Signal that you want to start the game. Only makes sense in room state and if you are chief.
+     * The server will check whether all players are ready and whether it believes the setup makes
+     * sense (e.g. more than one clan). If the server is satisfied, you will receive an onRunGame
+     * callback (all other clients in the room are notified the same way). Otherwise the server
+     * might answer with a warning, or might not answer at all.
+     */
+    int flib_netconn_send_startGame(flib_netconn *conn);
+
+    /**
+     * Allow/forbid players to join the room. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_toggleRestrictJoins(flib_netconn *conn);
+
+    /**
+     * Allow/forbid adding teams to the room. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_toggleRestrictTeams(flib_netconn *conn);
+
+
+// Send functions that are only needed for running a game
+
+    /**
+     * Send a teamchat message, forwarded from the engine. Only makes sense ingame.
+     * The server does not send a reply. In contrast to a Chat message, the server
+     * automatically converts this into an engine message and passes it on to the other
+     * clients.
+     */
+    int flib_netconn_send_teamchat(flib_netconn *conn, const char *msg);
+
+    /**
+     * Send an engine message. Only makes sense when ingame. In a networked game, you have to pass
+     * all the engine messages from the engine here, and they will be spread to all other clients
+     * in the game to keep the game in sync.
+     */
+    int flib_netconn_send_engineMessage(flib_netconn *conn, const uint8_t *message, size_t size);
+
+    /**
+     * Inform the server that the round has ended. Call this when the engine has disconnected,
+     * passing 1 if the round ended normally, 0 otherwise.
+     */
+    int flib_netconn_send_roundfinished(flib_netconn *conn, bool withoutError);
+
+
+
+
+
+// Callbacks that are important for connecting/disconnecting
+
+    /**
+     * onNickTaken is called when connecting to the server, if it turns out that there is already a
+     * player with the same nick.
+     * In order to proceed, a new nickname needs to be sent to the server using
+     * flib_netconn_send_nick() (or of course you can bail out and send a QUIT).
+     * If you don't set a callback, the netconn will automatically react by generating a new name.
+     */
+    void flib_netconn_onNickTaken(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context);
+
+    /**
+     * When connecting with a registered nickname, the server will ask for a password before
+     * admitting you in. This callback is called when that happens. As a reaction, you can send the
+     * password using flib_netconn_send_password. If you don't register a callback, the default
+     * behavior is to just quit in a way that will cause a disconnect with
+     * NETCONN_DISCONNECT_AUTH_FAILED.
+     *
+     * You can't just choose a new nickname when you receive this callback, because at that point
+     * the server has already accepted your nick.
+     */
+    void flib_netconn_onPasswordRequest(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context);
+
+    /**
+     * This is called when the server has accepted our nickname (and possibly password) and we have
+     * entered the lobby.
+     */
+    void flib_netconn_onConnected(flib_netconn *conn, void (*callback)(void *context), void* context);
+
+    /**
+     * This is always the last callback (unless the netconn is destroyed early), and the netconn
+     * should be destroyed when it is received. The reason for the disconnect is passed as one of
+     * the NETCONN_DISCONNECT_ constants. Sometimes a message is included as well, but that
+     * parameter might also be NULL.
+     */
+    void flib_netconn_onDisconnected(flib_netconn *conn, void (*callback)(void *context, int reason, const char *message), void* context);
+
+
+// Callbacks that make sense in most situations
+
+    /**
+     * Callback for several informational messages that should be displayed to the user
+     * (e.g. in the chat window), but do not require a reaction. If a game is running, you might
+     * want to redirect some of these messages to the engine as well so the user will see them.
+     */
+    void flib_netconn_onMessage(flib_netconn *conn, void (*callback)(void *context, int msgtype, const char *msg), void* context);
+
+    /**
+     * We received a chat message. Where this message belongs depends on the current state
+     * (lobby/room). If a game is running the message should be passed to the engine.
+     */
+    void flib_netconn_onChat(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *msg), void* context);
+
+    /**
+     * Callbacks for incremental room list updates. They will fire whenever these events occur,
+     * even before you first query the actual roomlist - so be sure not to blindly reference your
+     * room list in these callbacks. The server currently only sends updates when a room changes
+     * its name, so in order to update other room information you need to query the roomlist again
+     * (see send_request_roomlist / onRoomlist).
+     */
+    void flib_netconn_onRoomAdd(flib_netconn *conn, void (*callback)(void *context, const flib_room *room), void* context);
+    void flib_netconn_onRoomDelete(flib_netconn *conn, void (*callback)(void *context, const char *name), void* context);
+    void flib_netconn_onRoomUpdate(flib_netconn *conn, void (*callback)(void *context, const char *oldName, const flib_room *room), void* context);
+
+    /**
+     * Callbacks for players joining or leaving the lobby. In contrast to the roomlist updates, you
+     * will get a JOIN callback for every player already on the server when you join (and there is
+     * no direct way to query the current playerlist)
+     *
+     * NOTE: partMessage may be NULL.
+     */
+    void flib_netconn_onLobbyJoin(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context);
+    void flib_netconn_onLobbyLeave(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *partMessage), void* context);
+
+    /**
+     * This is called when the server informs us that one or more flags associated with a
+     * player/client have changed.
+     *
+     * nick is the name of the player, flags is a string containing one character for each modified
+     * flag (see below), and newFlagState signals whether the flags should be set to true or false.
+     *
+     * Some of these flags are important for protocol purposes (especially if they are set for you)
+     * while others are just informational. Also, some flags are only relevant for players who are
+     * in the same room as you, and the server will not inform you if they change for others.
+     *
+     * These are the currently known/used flags:
+     * a: Server admin. Always updated.
+     * h: Room chief. Updated when in the same room.
+     * r: Ready to play. Updated when in the same room.
+     * u: Registered user. Always updated.
+     *
+     * The server tells us the 'a' and 'u' flags for all players when we first join the lobby, and
+     * also tells us the 'r' and 'h' flags when we join or create a room. It assumes that all flags
+     * are initially false, so it will typically only tell you to set certain flags to true when
+     * transmitting the initial states. Reset the 'h' and 'r' flags to false when leaving a room,
+     * or when entering room state, to arrive at the right state for each player.
+     *
+     * The room chief state of yourself is particularly important because it determines whether you
+     * can modify settings of the current room. Generally, when you create a room you start out
+     * being room chief, and when you join an existing room you are not. However, if the original
+     * chief leaves a room, the server can choose a new chief, and if that happens the chief flag
+     * will be transferred to someone else.
+     */
+    void flib_netconn_onClientFlags(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *flags, bool newFlagState), void *context);
+
+// Callbacks that happen only in response to specific requests
+
+    /**
+     * Response to flib_netconn_send_request_roomlist().
+     * The rooms array contains the current state of all rooms on the server.
+     */
+    void flib_netconn_onRoomlist(flib_netconn *conn, void (*callback)(void *context, const flib_room **rooms, int roomCount), void* context);
+
+    /**
+     * Response to flib_netconn_send_joinRoom, flib_netconn_send_playerFollow or
+     * flib_netconn_send_createRoom.
+     *
+     * You just left the lobby and entered a room.
+     * If chief is true, you can and should send a full configuration for the room now. This
+     * consists of ammo, scheme, script and map, where map apparently has to come last.
+     */
+    void flib_netconn_onEnterRoom(flib_netconn *conn, void (*callback)(void *context, bool chief), void *context);
+
+    /**
+     * Response to flib_netconn_send_addTeam.
+     * The server might reject your team for several reasons, e.g. because it has the same name as
+     * an existing team, or because the room chief restricted adding new teams. If the team is
+     * accepted by the server, this callback is fired.
+     *
+     * If you are the room chief, you are expected to provide the hog count for your own team now
+     * using flib_netconn_send_teamHogCount. The color of the team is already set to the one you
+     * provided in addTeam.
+     */
+    void flib_netconn_onTeamAccepted(flib_netconn *conn, void (*callback)(void *context, const char *team), void *context);
+
+    /**
+     * When you query the server vars with flib_netconn_send_getServerVars (only works as admin),
+     * the server replies with a list of them. This callback is called for each entry in that list.
+     */
+    void flib_netconn_onServerVar(flib_netconn *conn, void (*callback)(void *context, const char *name, const char *value), void *context);
+
+
+// Callbacks that are only relevant in a room
+
+    /**
+     * You just left a room and entered the lobby again.
+     * reason is one of the NETCONN_ROOMLEAVE_ constants (usually a kick).
+     * This will not be called when you actively leave a room using PART.
+     * Don't confuse with onRoomLeave, which indicates that *someone else* left the room.
+     */
+    void flib_netconn_onLeaveRoom(flib_netconn *conn, void (*callback)(void *context, int reason, const char *message), void *context);
+
+    /**
+     * Someone joined or left the room you are currently in.
+     * Analogous to onLobbyJoin/leave, you will receive the join callback for all players that are
+     * already in the room when you join, including for yourself (this is actually how it is
+     * determined that you joined a room).
+     *
+     * However, you will *not* receive onRoomLeave messages for everyone when you leave the room.
+     */
+    void flib_netconn_onRoomJoin(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context);
+    void flib_netconn_onRoomLeave(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *partMessage), void* context);
+
+    /**
+     * A new team was added to the room. The person who adds a team does NOT receive this callback
+     * (he gets onTeamAccepted instead).
+     *
+     * The team does not contain bindings, stats, weaponset, color or the number of hogs (but it is
+     * assumed to be the default of 4).
+     *
+     * If you receive this message and you are the room chief, you may want to send a color and hog
+     * count for this team using flib_netconn_send_teamHogCount / teamColor for QtFrontend
+     * compatibility.
+     *
+     * The server currently sends another message with the color of the team to the same recipients
+     * as this teamAdd message, which will trigger an onTeamColorChanged callback. See the
+     * description of flib_netconn_send_addTeam for more information.
+     */
+    void flib_netconn_onTeamAdd(flib_netconn *conn, void (*callback)(void *context, const flib_team *team), void *context);
+
+    /**
+     * A team was removed from the room. The person who removed the team will not receive this
+     * callback.
+     */
+    void flib_netconn_onTeamDelete(flib_netconn *conn, void (*callback)(void *context, const char *teamname), void *context);
+
+    /**
+     * The number of hogs in a team has been changed by the room chief. If you are the chief and
+     * change the number of hogs yourself, you will not receive this callback.
+     */
+    void flib_netconn_onHogCountChanged(flib_netconn *conn, void (*callback)(void *context, const char *teamName, int hogs), void *context);
+
+    /**
+     * The color of a team has been set or changed. The client who set or changed the color will
+     * not receive this callback.
+     *
+     * Normally, only the chief can change the color of a team. However, this message is also
+     * generated when a team is added, so you can receive it even as chief.
+     */
+    void flib_netconn_onTeamColorChanged(flib_netconn *conn, void (*callback)(void *context, const char *teamName, int colorIndex), void *context);
+
+    /**
+     * The room chief has changed the game scheme (or you just joined a room).
+     * You will not receive this callback if you changed the scheme yourself.
+     */
+    void flib_netconn_onSchemeChanged(flib_netconn *conn, void (*callback)(void *context, const flib_scheme *scheme), void *context);
+
+    /**
+     * The room chief has changed the map (or you just joined a room). Only non-chiefs receive these
+     * messages.
+     *
+     * To reduce the number of callback functions, the netconn keeps track of the current map
+     * settings and always passes the entire current map config, but informs the callee about what
+     * has changed (see the NETCONN_MAPCHANGE_ constants).
+     *
+     * Caution: Due to the way the protocol works, the map might not be complete at this point if it
+     * is a hand-drawn map, because the "full" map config does not include the drawn map data.
+     */
+    void flib_netconn_onMapChanged(flib_netconn *conn, void (*callback)(void *context, const flib_map *map, int changetype), void *context);
+
+    /**
+     * The room chief has changed the game style (or you just joined a room). If you are the chief
+     * and change the style yourself, you will not receive this callback.
+     */
+    void flib_netconn_onScriptChanged(flib_netconn *conn, void (*callback)(void *context, const char *script), void *context);
+
+    /**
+     * The room chief has changed the weaponset (or you just joined a room). If you are the chief
+     * and change the weaponset yourself, you will not receive this callback.
+     */
+    void flib_netconn_onWeaponsetChanged(flib_netconn *conn, void (*callback)(void *context, const flib_weaponset *weaponset), void *context);
+
+    /**
+     * The game is starting. Fire up the engine and join in!
+     * You can let the netconn generate the right game setup using flib_netconn_create_gamesetup
+     */
+    void flib_netconn_onRunGame(flib_netconn *conn, void (*callback)(void *context), void *context);
+
+    /**
+     * You are in a room, a game is in progress, and the server is sending you the new input for the
+     * engine to keep up to date with the current happenings. Pass it on to the engine using
+     * flib_gameconn_send_enginemsg.
+     */
+    void flib_netconn_onEngineMessage(flib_netconn *conn, void (*callback)(void *context, const uint8_t *message, size_t size), void *context);
+
+#endif
--- a/project_files/frontlib/net/netconn_internal.h	Sun Jun 09 12:20:19 2013 +0200
+++ b/project_files/frontlib/net/netconn_internal.h	Sun Jun 09 12:22:53 2013 +0200
@@ -1,151 +1,151 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-/**
- * Common definitions needed by netconn functions, to allow splitting them into several files.
- */
-
-#ifndef NETCONN_INTERNAL_H_
-#define NETCONN_INTERNAL_H_
-
-#include "netconn.h"
-#include "netbase.h"
-#include "../model/map.h"
-#include "../model/team.h"
-#include "../model/weapon.h"
-#include "../model/room.h"
-
-#include <stdbool.h>
-#include <stdint.h>
-#include <stddef.h>
-
-struct _flib_netconn {
-	flib_netbase *netBase;
-	char *playerName;
-	char *dataDirPath;
-
-	int netconnState;			//!< One of the NETCONN_STATE constants
-
-	bool isChief;				//!< Player can modify the current room
-	flib_map *map;
-	flib_teamlist pendingTeamlist;
-	flib_teamlist teamlist;
-	flib_scheme *scheme;
-	char *style;
-	flib_weaponset *weaponset;
-
-	void (*onMessageCb)(void *context, int msgtype, const char *msg);
-	void *onMessageCtx;
-
-	void (*onConnectedCb)(void *context);
-	void *onConnectedCtx;
-
-	void (*onDisconnectedCb)(void *context, int reason, const char *message);
-	void *onDisconnectedCtx;
-
-	void (*onRoomlistCb)(void *context, const flib_room **rooms, int roomCount);
-	void *onRoomlistCtx;
-
-	void (*onRoomAddCb)(void *context, const flib_room *room);
-	void *onRoomAddCtx;
-
-	void (*onRoomDeleteCb)(void *context, const char *name);
-	void *onRoomDeleteCtx;
-
-	void (*onRoomUpdateCb)(void *context, const char *oldName, const flib_room *room);
-	void *onRoomUpdateCtx;
-
-	void (*onClientFlagsCb)(void *context, const char *nick, const char *flags, bool newFlagState);
-	void *onClientFlagsCtx;
-
-	void (*onChatCb)(void *context, const char *nick, const char *msg);
-	void *onChatCtx;
-
-	void (*onLobbyJoinCb)(void *context, const char *nick);
-	void *onLobbyJoinCtx;
-
-	void (*onLobbyLeaveCb)(void *context, const char *nick, const char *partMessage);
-	void *onLobbyLeaveCtx;
-
-	void (*onRoomJoinCb)(void *context, const char *nick);
-	void *onRoomJoinCtx;
-
-	void (*onRoomLeaveCb)(void *context, const char *nick, const char *partMessage);
-	void *onRoomLeaveCtx;
-
-	void (*onNickTakenCb)(void *context, const char *nick);
-	void *onNickTakenCtx;
-
-	void (*onPasswordRequestCb)(void *context, const char *nick);
-	void *onPasswordRequestCtx;
-
-	void (*onEnterRoomCb)(void *context, bool chief);
-	void *onEnterRoomCtx;
-
-	void (*onLeaveRoomCb)(void *context, int reason, const char *message);
-	void *onLeaveRoomCtx;
-
-	void (*onTeamAddCb)(void *context, const flib_team *team);
-	void *onTeamAddCtx;
-
-	void (*onTeamDeleteCb)(void *context, const char *teamname);
-	void *onTeamDeleteCtx;
-
-	void (*onRunGameCb)(void *context);
-	void *onRunGameCtx;
-
-	void (*onTeamAcceptedCb)(void *context, const char *teamName);
-	void *onTeamAcceptedCtx;
-
-	void (*onHogCountChangedCb)(void *context, const char *teamName, int hogs);
-	void *onHogCountChangedCtx;
-
-	void (*onTeamColorChangedCb)(void *context, const char *teamName, int colorIndex);
-	void *onTeamColorChangedCtx;
-
-	void (*onEngineMessageCb)(void *context, const uint8_t *message, size_t size);
-	void *onEngineMessageCtx;
-
-	void (*onSchemeChangedCb)(void *context, const flib_scheme *scheme);
-	void *onSchemeChangedCtx;
-
-	void (*onMapChangedCb)(void *context, const flib_map *map, int changetype);
-	void *onMapChangedCtx;
-
-	void (*onScriptChangedCb)(void *context, const char *script);
-	void *onScriptChangedCtx;
-
-	void (*onWeaponsetChangedCb)(void *context, const flib_weaponset *weaponset);
-	void *onWeaponsetChangedCtx;
-
-	void (*onServerVarCb)(void *context, const char *name, const char *value);
-	void *onServerVarCtx;
-
-	bool running;
-	bool destroyRequested;
-};
-
-void netconn_clearCallbacks(flib_netconn *conn);
-void netconn_leaveRoom(flib_netconn *conn);
-void netconn_setMap(flib_netconn *conn, const flib_map *map);
-void netconn_setWeaponset(flib_netconn *conn, const flib_weaponset *weaponset);
-void netconn_setScript(flib_netconn *conn, const char *script);
-void netconn_setScheme(flib_netconn *conn, const flib_scheme *scheme);
-
-#endif
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/**
+ * Common definitions needed by netconn functions, to allow splitting them into several files.
+ */
+
+#ifndef NETCONN_INTERNAL_H_
+#define NETCONN_INTERNAL_H_
+
+#include "netconn.h"
+#include "netbase.h"
+#include "../model/map.h"
+#include "../model/team.h"
+#include "../model/weapon.h"
+#include "../model/room.h"
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stddef.h>
+
+struct _flib_netconn {
+    flib_netbase *netBase;
+    char *playerName;
+    char *dataDirPath;
+
+    int netconnState;           //!< One of the NETCONN_STATE constants
+
+    bool isChief;               //!< Player can modify the current room
+    flib_map *map;
+    flib_teamlist pendingTeamlist;
+    flib_teamlist teamlist;
+    flib_scheme *scheme;
+    char *style;
+    flib_weaponset *weaponset;
+
+    void (*onMessageCb)(void *context, int msgtype, const char *msg);
+    void *onMessageCtx;
+
+    void (*onConnectedCb)(void *context);
+    void *onConnectedCtx;
+
+    void (*onDisconnectedCb)(void *context, int reason, const char *message);
+    void *onDisconnectedCtx;
+
+    void (*onRoomlistCb)(void *context, const flib_room **rooms, int roomCount);
+    void *onRoomlistCtx;
+
+    void (*onRoomAddCb)(void *context, const flib_room *room);
+    void *onRoomAddCtx;
+
+    void (*onRoomDeleteCb)(void *context, const char *name);
+    void *onRoomDeleteCtx;
+
+    void (*onRoomUpdateCb)(void *context, const char *oldName, const flib_room *room);
+    void *onRoomUpdateCtx;
+
+    void (*onClientFlagsCb)(void *context, const char *nick, const char *flags, bool newFlagState);
+    void *onClientFlagsCtx;
+
+    void (*onChatCb)(void *context, const char *nick, const char *msg);
+    void *onChatCtx;
+
+    void (*onLobbyJoinCb)(void *context, const char *nick);
+    void *onLobbyJoinCtx;
+
+    void (*onLobbyLeaveCb)(void *context, const char *nick, const char *partMessage);
+    void *onLobbyLeaveCtx;
+
+    void (*onRoomJoinCb)(void *context, const char *nick);
+    void *onRoomJoinCtx;
+
+    void (*onRoomLeaveCb)(void *context, const char *nick, const char *partMessage);
+    void *onRoomLeaveCtx;
+
+    void (*onNickTakenCb)(void *context, const char *nick);
+    void *onNickTakenCtx;
+
+    void (*onPasswordRequestCb)(void *context, const char *nick);
+    void *onPasswordRequestCtx;
+
+    void (*onEnterRoomCb)(void *context, bool chief);
+    void *onEnterRoomCtx;
+
+    void (*onLeaveRoomCb)(void *context, int reason, const char *message);
+    void *onLeaveRoomCtx;
+
+    void (*onTeamAddCb)(void *context, const flib_team *team);
+    void *onTeamAddCtx;
+
+    void (*onTeamDeleteCb)(void *context, const char *teamname);
+    void *onTeamDeleteCtx;
+
+    void (*onRunGameCb)(void *context);
+    void *onRunGameCtx;
+
+    void (*onTeamAcceptedCb)(void *context, const char *teamName);
+    void *onTeamAcceptedCtx;
+
+    void (*onHogCountChangedCb)(void *context, const char *teamName, int hogs);
+    void *onHogCountChangedCtx;
+
+    void (*onTeamColorChangedCb)(void *context, const char *teamName, int colorIndex);
+    void *onTeamColorChangedCtx;
+
+    void (*onEngineMessageCb)(void *context, const uint8_t *message, size_t size);
+    void *onEngineMessageCtx;
+
+    void (*onSchemeChangedCb)(void *context, const flib_scheme *scheme);
+    void *onSchemeChangedCtx;
+
+    void (*onMapChangedCb)(void *context, const flib_map *map, int changetype);
+    void *onMapChangedCtx;
+
+    void (*onScriptChangedCb)(void *context, const char *script);
+    void *onScriptChangedCtx;
+
+    void (*onWeaponsetChangedCb)(void *context, const flib_weaponset *weaponset);
+    void *onWeaponsetChangedCtx;
+
+    void (*onServerVarCb)(void *context, const char *name, const char *value);
+    void *onServerVarCtx;
+
+    bool running;
+    bool destroyRequested;
+};
+
+void netconn_clearCallbacks(flib_netconn *conn);
+void netconn_leaveRoom(flib_netconn *conn);
+void netconn_setMap(flib_netconn *conn, const flib_map *map);
+void netconn_setWeaponset(flib_netconn *conn, const flib_weaponset *weaponset);
+void netconn_setScript(flib_netconn *conn, const char *script);
+void netconn_setScheme(flib_netconn *conn, const flib_scheme *scheme);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/CMakeLists.txt	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,66 @@
+#the usual set of dependencies
+find_package(OpenGL REQUIRED)
+find_package(GLEW REQUIRED)
+find_package(SDL REQUIRED)
+find_package(SDL_mixer REQUIRED)
+find_package(SDL_net REQUIRED)
+find_package(SDL_image REQUIRED)
+find_package(SDL_ttf REQUIRED)
+
+#compile our rtl implementation
+include_directories(${GLEW_INCLUDE_DIRS})
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/rtl)
+add_subdirectory(rtl)
+
+configure_file(${CMAKE_SOURCE_DIR}/hedgewars/config.inc.in ${CMAKE_CURRENT_BINARY_DIR}/config.inc)
+
+#get the list of pas files that are going to be converted and compiled
+file(GLOB engine_sources_pas "${CMAKE_SOURCE_DIR}/hedgewars/*.pas")
+#TODO: temporary until cmake can configure itself accordingly
+list(REMOVE_ITEM engine_sources_pas "${CMAKE_SOURCE_DIR}/hedgewars/uWeb.pas")
+list(REMOVE_ITEM engine_sources_pas "${CMAKE_SOURCE_DIR}/hedgewars/uVideoRec.pas")
+list(REMOVE_ITEM engine_sources_pas "${CMAKE_SOURCE_DIR}/hedgewars/uTouch.pas")
+list(REMOVE_ITEM engine_sources_pas "${CMAKE_SOURCE_DIR}/hedgewars/PNGh.pas")
+list(REMOVE_ITEM engine_sources_pas "${CMAKE_SOURCE_DIR}/hedgewars/pas2cSystem.pas")
+list(REMOVE_ITEM engine_sources_pas "${CMAKE_SOURCE_DIR}/hedgewars/pas2cRedo.pas")
+list(REMOVE_ITEM engine_sources_pas "${CMAKE_SOURCE_DIR}/hedgewars/hwLibrary.pas")
+
+foreach(sourcefile ${engine_sources_pas})
+    get_filename_component(sourcename ${sourcefile} NAME_WE) #drops .pas
+    set(engine_sources "${CMAKE_CURRENT_BINARY_DIR}/${sourcename}.c" ${engine_sources})
+endforeach()
+
+#invoke pas2c on our pas files
+add_custom_command(OUTPUT ${engine_sources}
+        COMMAND "${EXECUTABLE_OUTPUT_PATH}/pas2c${CMAKE_EXECUTABLE_SUFFIX}"
+        ARGS -n "hwengine"
+             -i "${CMAKE_SOURCE_DIR}/hedgewars"
+             -o "${CMAKE_CURRENT_BINARY_DIR}"
+             -a "${CMAKE_CURRENT_BINARY_DIR}"
+        DEPENDS pas2c
+    )
+add_custom_target(engine_c DEPENDS ${engine_sources})
+
+
+#compile the c files
+add_executable(hwengine WIN32 ${engine_sources})
+
+target_link_libraries(hwengine  fpcrtl
+                                ${LUA_LIBRARY}
+                                ${OPENGL_LIBRARY}
+                                ${SDL_LIBRARY}
+                                ${SDLMIXER_LIBRARY}
+                                ${SDLNET_LIBRARY}
+                                ${SDLIMAGE_LIBRARY}
+                                ${SDLTTF_LIBRARY}
+                                ${GLEW_LIBRARY}
+                                physfs
+                                physlayer
+                                #TODO: add other libraries
+                            )
+if(APPLE)
+    target_link_libraries(hwengine IOKit SDLmain)
+endif()
+
+install(PROGRAMS "${EXECUTABLE_OUTPUT_PATH}/hwengine${CMAKE_EXECUTABLE_SUFFIX}" DESTINATION ${target_binary_install_dir})
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/CMakeLists.txt	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,16 @@
+
+include_directories(${GLEW_INCLUDE_PATH})
+
+file(GLOB fpcrtl_src *.c)
+
+add_library(fpcrtl ${fpcrtl_src})
+
+#if(WEBGL)
+#    set_target_properties(fpcrtl PROPERTIES PREFIX "em")
+#    set_target_properties(fpcrtl PROPERTIES SUFFIX ".bc")
+#endif(WEBGL)
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/GL.h	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,8 @@
+#pragma once
+
+#ifdef __APPLE__
+#include <OpenGL/gl.h>
+#else
+#include "GL/gl.h"
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/Math.h	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,4 @@
+#pragma once
+
+#include <math.h>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/SysUtils.h	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,41 @@
+#ifndef _FPCRTL_SYSUTILS_H_
+#define _FPCRTL_SYSUTILS_H_
+
+#include "Types.h"
+
+// EFFECTS: return the current date time in pascal notation
+//          http://www.merlyn.demon.co.uk/del-prgg.htm#TDT
+TDateTime   fpcrtl_now();
+#define     now                     fpcrtl_now
+#define     Now                     fpcrtl_now
+
+// EFFECTS: return the current time
+//          http://www.merlyn.demon.co.uk/del-prgg.htm#TDT
+TDateTime   fpcrtl_time();
+
+
+// EFFECTS: return the current date
+//          http://www.merlyn.demon.co.uk/del-prgg.htm#TDT
+TDateTime   fpcrtl_date();
+#define     date                    fpcrtl_date
+#define     Date                    fpcrtl_date
+
+// EFFECTS: Trim strips blank characters (spaces) at the beginning and end of S
+// and returns the resulting string. Only #32 characters are stripped.
+// If the string contains only spaces, an empty string is returned.
+string255   fpcrtl_trim(string255 s);
+#define     trim                    fpcrtl_trim
+#define     Trim                    fpcrtl_trim
+
+Integer     fpcrtl_strToInt(string255 s);
+#define     StrToInt                fpcrtl_strToInt
+#define     strToInt                fpcrtl_strToInt
+
+string255   fpcrtl_extractFileName(string255 f);
+#define     fpcrtl_ExtractFileName  fpcrtl_extractFileName
+
+string255   fpcrtl_strPas(PChar);
+#define     fpcrtl_StrPas           fpcrtl_strPas
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/Types.h	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,39 @@
+#ifndef _TYPES_H_
+#define _TYPES_H_
+
+#include "pas2c.h"
+
+/*
+ * Not very useful currently
+ */
+
+typedef double TDate;
+typedef double TTime;
+typedef double TDateTime;
+typedef string255 TMonthNameArray[13];
+typedef string255 TWeekNameArray[8];
+
+typedef struct {
+    Byte CurrencyFormat;
+    Byte NegCurrFormat;
+    Char ThousandSeparator;
+    Char DecimalSeparator;
+    Byte CurrencyDecimals;
+    Char DateSeparator;
+    Char TimeSeparator;
+    Char ListSeparator;
+    string255 CurrencyString;
+    string255 ShortDateFormat;
+    string255 LongDateFormat;
+    string255 TimeAMString;
+    string255 TimePMString;
+    string255 ShortTimeFormat;
+    string255 LongTimeFormat;
+    TMonthNameArray ShortMonthNames;
+    TMonthNameArray LongMonthNames;
+    TWeekNameArray ShortDayNames;
+    TWeekNameArray LongDayNames;
+    Word TwoDigitYearCenturyWindow;
+}TFormatSettings;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/fileio.c	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,226 @@
+/*
+ * XXX: assume all files are text files
+ */
+
+#include "misc.h"
+#include "fileio.h"
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <sys/stat.h>
+
+io_result_t IOResult;
+int FileMode;
+
+static void init(File f) {
+    f->fp = NULL;
+    f->eof = 0;
+    f->mode = NULL;
+    f->record_len = 0;
+}
+
+void fpcrtl_assign__vars(File *f, string255 name) {
+    FIX_STRING(name);
+    *f = (File) malloc(sizeof(file_wrapper_t));
+    strcpy((*f)->file_name, name.str);
+    init(*f);
+}
+
+void fpcrtl_reset1(File f) {
+    f->fp = fopen(f->file_name, "r");
+    if (!f->fp) {
+        IOResult = IO_ERROR_DUMMY;
+        printf("Failed to open %s\n", f->file_name);
+        return;
+    } else {
+#ifdef FPCRTL_DEBUG
+        printf("Opened %s\n", f->file_name);
+#endif
+    }
+    IOResult = IO_NO_ERROR;
+    f->mode = "r";
+}
+
+void fpcrtl_reset2(File f, int l) {
+    f->eof = 0;
+    f->fp = fopen(f->file_name, "rb");
+    if (!f->fp) {
+        IOResult = IO_ERROR_DUMMY;
+        printf("Failed to open %s\n", f->file_name);
+        return;
+    }
+    IOResult = IO_NO_ERROR;
+    f->mode = "rb";
+    f->record_len = l;
+}
+
+void __attribute__((overloadable)) fpcrtl_rewrite(File f) {
+    f->fp = fopen(f->file_name, "w+");
+    if (!f->fp) {
+        IOResult = IO_ERROR_DUMMY;
+        return;
+    }
+    IOResult = IO_NO_ERROR;
+    f->mode = "w+";
+}
+
+void __attribute__((overloadable)) fpcrtl_rewrite(File f, Integer l) {
+    IOResult = IO_NO_ERROR;
+    fpcrtl_rewrite(f);
+    if (f->fp) {
+        f->record_len = l;
+    }
+}
+
+void fpcrtl_close(File f) {
+    IOResult = IO_NO_ERROR;
+    fclose(f->fp);
+    free(f);
+}
+
+boolean fpcrtl_eof(File f) {
+    IOResult = IO_NO_ERROR;
+    if (f->eof || f->fp == NULL || feof(f->fp)) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+void __attribute__((overloadable)) fpcrtl_readLn(File f) {
+    IOResult = IO_NO_ERROR;
+    char line[256];
+    if (fgets(line, sizeof(line), f->fp) == NULL) {
+        f->eof = 1;
+    }
+    if (feof(f->fp)) {
+        f->eof = 1;
+    }
+}
+
+void __attribute__((overloadable)) fpcrtl_readLn__vars(File f, Integer *i) {
+    string255 s;
+
+    if (feof(f->fp)) {
+        f->eof = 1;
+        return;
+    }
+
+    fpcrtl_readLn__vars(f, &s);
+
+    *i = atoi(s.str);
+}
+
+void __attribute__((overloadable)) fpcrtl_readLn__vars(File f, LongWord *i) {
+    string255 s;
+
+    if (feof(f->fp)) {
+        f->eof = 1;
+        return;
+    }
+
+    fpcrtl_readLn__vars(f, &s);
+
+    *i = atoi(s.str);
+}
+
+void __attribute__((overloadable)) fpcrtl_readLn__vars(File f, string255 *s) {
+
+    if (fgets(s->str, 255, f->fp) == NULL) {
+
+        s->len = 0;
+        s->str[0] = 0;
+
+        f->eof = 1;
+        return;
+    }
+
+    if (feof(f->fp)) {
+        s->len = 0;
+        f->eof = 1;
+        return;
+    }
+
+    IOResult = IO_NO_ERROR;
+
+    s->len = strlen(s->str);
+    if ((s->len > 0) && (s->str[s->len - 1] == '\n')) {
+        s->str[s->len - 1] = 0;
+        s->len--;
+    }
+}
+
+void __attribute__((overloadable)) fpcrtl_write(File f, string255 s) {
+    FIX_STRING(s);
+    fprintf(f->fp, "%s", s.str);
+}
+
+void __attribute__((overloadable)) fpcrtl_write(FILE *f, string255 s) {
+    FIX_STRING(s);
+    fprintf(f, "%s", s.str);
+}
+
+void __attribute__((overloadable)) fpcrtl_writeLn(File f, string255 s) {
+    FIX_STRING(s);
+    fprintf(f->fp, "%s\n", s.str);
+}
+
+void __attribute__((overloadable)) fpcrtl_writeLn(FILE *f, string255 s) {
+    FIX_STRING(s);
+    fprintf(f, "%s\n", s.str);
+}
+
+void fpcrtl_blockRead__vars(File f, void *buf, Integer count, Integer *result) {
+    assert(f->record_len > 0);
+    *result = fread(buf, f->record_len, count, f->fp);
+}
+
+/*
+ * XXX: dummy blockWrite
+ */
+void fpcrtl_blockWrite__vars(File f, const void *buf, Integer count,
+        Integer *result) {
+    assert(0);
+}
+
+bool fpcrtl_directoryExists(string255 dir) {
+
+    struct stat st;
+    FIX_STRING(dir);
+
+    IOResult = IO_NO_ERROR;
+
+#ifdef FPCRTL_DEBUG
+    printf("Warning: directoryExists is called. This may not work when compiled to js.\n");
+#endif
+
+    if (stat(dir.str, &st) == 0) {
+        return true;
+    }
+
+    return false;
+}
+
+bool fpcrtl_fileExists(string255 filename) {
+
+    FIX_STRING(filename);
+
+    IOResult = IO_NO_ERROR;
+
+    FILE *fp = fopen(filename.str, "r");
+    if (fp) {
+        fclose(fp);
+        return true;
+    }
+    return false;
+}
+
+void __attribute__((overloadable)) fpcrtl_flush(Text f) {
+    printf("flush not implemented\n");
+    assert(0);
+}
+
+void __attribute__((overloadable)) fpcrtl_flush(FILE *f) {
+    fflush(f);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/fileio.h	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,78 @@
+#ifndef FILEIO_H_
+#define FILEIO_H_
+
+#include <stdio.h>
+#include "Types.h"
+#include "misc.h"
+
+extern        int                                       FileMode;
+
+typedef enum{
+    IO_NO_ERROR = 0,
+    IO_ERROR_DUMMY = 1
+}io_result_t;
+
+extern        io_result_t                               IOResult;
+
+typedef struct{
+    FILE        *fp;
+    const char* mode;
+    char        file_name[256];
+    int         eof;
+    int            record_len;
+}file_wrapper_t;
+
+typedef     file_wrapper_t*                             File;
+typedef     File                                        Text;
+typedef     Text                                        TextFile;
+
+void        __attribute__((overloadable))               fpcrtl_readLn(File f);
+#define     fpcrtl_readLn1(f)                           fpcrtl_readLn(f)
+
+void        __attribute__((overloadable))               fpcrtl_readLn__vars(File f, Integer *i);
+void        __attribute__((overloadable))               fpcrtl_readLn__vars(File f, LongWord *i);
+void        __attribute__((overloadable))               fpcrtl_readLn__vars(File f, string255 *s);
+#define     fpcrtl_readLn2(f, t)                        fpcrtl_readLn__vars(f, &(t))
+
+#define     fpcrtl_readLn(...)                          macro_dispatcher(fpcrtl_readLn, __VA_ARGS__)(__VA_ARGS__)
+
+
+void        fpcrtl_blockRead__vars(File f, void *buf, Integer count, Integer *result);
+#define     fpcrtl_blockRead(f, buf, count, result)     fpcrtl_blockRead__vars(f, &(buf), count, &(result))
+#define     fpcrtl_BlockRead                            fpcrtl_blockRead
+
+#define     fpcrtl_assign(f, name)                      fpcrtl_assign__vars(&f, name)
+void        fpcrtl_assign__vars(File *f, string255 name);
+
+boolean     fpcrtl_eof(File f);
+
+void        fpcrtl_reset1(File f);
+void        fpcrtl_reset2(File f, Integer l);
+#define     fpcrtl_reset1(f)                            fpcrtl_reset1(f)
+#define     fpcrtl_reset2(f, l)                         fpcrtl_reset2(f, l)
+#define     fpcrtl_reset(...)                           macro_dispatcher(fpcrtl_reset, __VA_ARGS__)(__VA_ARGS__)
+
+void        fpcrtl_close(File f);
+
+void        __attribute__((overloadable))               fpcrtl_rewrite(File f);
+void        __attribute__((overloadable))               fpcrtl_rewrite(File f, Integer l);
+
+void        __attribute__((overloadable))               fpcrtl_flush(Text f);
+void        __attribute__((overloadable))               fpcrtl_flush(FILE *f);
+
+void        __attribute__((overloadable))               fpcrtl_write(File f, string255 s);
+void        __attribute__((overloadable))               fpcrtl_write(FILE *f, string255 s);
+void        __attribute__((overloadable))               fpcrtl_writeLn(File f, string255 s);
+void        __attribute__((overloadable))               fpcrtl_writeLn(FILE *f, string255 s);
+
+void        fpcrtl_blockWrite__vars(File f, const void *buf, Integer count, Integer *result);
+#define     fpcrtl_blockWrite(f, buf, count, result)    fpcrtl_blockWrite__vars(f, &(buf), count, &(result))
+#define     fpcrtl_BlockWrite                           fpcrtl_blockWrite
+
+bool        fpcrtl_directoryExists(string255 dir);
+#define     fpcrtl_DirectoryExists                      fpcrtl_directoryExists
+
+bool        fpcrtl_fileExists(string255 filename);
+#define     fpcrtl_FileExists                           fpcrtl_fileExists
+
+#endif /* FILEIO_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/fpcrtl.h	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,192 @@
+#ifndef _FPCRTL_H_
+#define _FPCRTL_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <math.h>
+
+#include "SysUtils.h"
+#include "system.h"
+#include "misc.h"
+#include "fileio.h"
+#include "pmath.h"
+
+#ifndef EMSCRIPTEN
+#if __APPLE__
+#define main SDL_main
+#endif
+#include "GL/glew.h"
+#endif
+
+#define fpcrtl_memcpy                       memcpy
+
+#define luapas_lua_gettop                   lua_gettop
+#define luapas_lua_close                    lua_close
+#define luapas_lua_createtable              lua_createtable
+#define luapas_lua_error                    lua_error
+#define luapas_lua_gc                       lua_gc
+#define luapas_lua_getfield                 lua_getfield
+#define luapas_lua_objlen                   lua_objlen
+#define luapas_lua_call                     lua_call
+#define luapas_lua_pcall                    lua_pcall
+#define luapas_lua_pushboolean              lua_pushboolean
+#define luapas_lua_pushcclosure             lua_pushcclosure
+#define luapas_lua_pushinteger              lua_pushinteger
+#define luapas_lua_pushnil                  lua_pushnil
+#define luapas_lua_pushnumber               lua_pushnumber
+#define luapas_lua_pushlstring              lua_pushlstring
+#define luapas_lua_pushstring               lua_pushstring
+#define luapas_lua_pushvalue                lua_pushvalue
+#define luapas_lua_rawgeti                  lua_rawgeti
+#define luapas_lua_setfield                 lua_setfield
+#define luapas_lua_settop                   lua_settop
+#define luapas_lua_toboolean                lua_toboolean
+#define luapas_lua_tointeger                lua_tointeger
+#define luapas_lua_tolstring                lua_tolstring
+#define luapas_lua_tonumber                 lua_tonumber
+#define luapas_lua_type                     lua_type
+#define luapas_lua_typename                 lua_typename
+#define luapas_luaL_argerror                luaL_argerror
+#define luapas_luaL_checkinteger            luaL_checkinteger
+#define luapas_luaL_checklstring            luaL_checklstring
+#define luapas_luaL_loadfile                luaL_loadfile
+#define luapas_luaL_loadstring              luaL_loadstring
+#define luapas_luaL_newstate                luaL_newstate
+#define luapas_luaL_optinteger              luaL_optinteger
+#define luapas_luaL_optlstring              luaL_optlstring
+#define luapas_luaL_prepbuffer              luaL_prepbuffer
+#define luapas_luaL_ref                     luaL_ref
+#define luapas_luaL_unref                   luaL_unref
+#define luapas_luaopen_base                 luaopen_base
+#define luapas_luaopen_math                 luaopen_math
+#define luapas_luaopen_string               luaopen_string
+#define luapas_luaopen_table                luaopen_table
+
+#define sdlh_IMG_Load                       IMG_Load
+
+#ifndef EMSCRIPTEN
+#define sdlh_Mix_AllocateChannels           Mix_AllocateChannels
+#define sdlh_Mix_CloseAudio                 Mix_CloseAudio
+#define sdlh_Mix_FadeInChannelTimed         Mix_FadeInChannelTimed
+#define sdlh_Mix_FadeInMusic                Mix_FadeInMusic
+#define sdlh_Mix_FadeOutChannel             Mix_FadeOutChannel
+#define sdlh_Mix_FreeChunk                  Mix_FreeChunk
+#define sdlh_Mix_FreeMusic                  Mix_FreeMusic
+#define sdlh_Mix_HaltChannel                Mix_HaltChannel
+#define sdlh_Mix_HaltMusic                  Mix_HaltMusic
+#define sdlh_Mix_LoadMUS                    Mix_LoadMUS
+#define sdlh_Mix_LoadWAV_RW                 Mix_LoadWAV_RW
+#define sdlh_Mix_OpenAudio                  Mix_OpenAudio
+#define sdlh_Mix_PauseMusic                 Mix_PauseMusic
+#define sdlh_Mix_PlayChannelTimed           Mix_PlayChannelTimed
+#define sdlh_Mix_Playing                    Mix_Playing
+#define sdlh_Mix_ResumeMusic                Mix_ResumeMusic
+#define sdlh_Mix_Volume                     Mix_Volume
+#define sdlh_Mix_VolumeMusic                Mix_VolumeMusic
+#else
+#define sdlh_Mix_AllocateChannels           stub_Mix_AllocateChannels
+#define sdlh_Mix_CloseAudio                 stub_Mix_CloseAudio
+#define sdlh_Mix_FadeInChannelTimed         stub_Mix_FadeInChannelTimed
+#define sdlh_Mix_FadeInMusic                stub_Mix_FadeInMusic
+#define sdlh_Mix_FadeOutChannel             stub_Mix_FadeOutChannel
+#define sdlh_Mix_FreeChunk                  stub_Mix_FreeChunk
+#define sdlh_Mix_FreeMusic                  stub_Mix_FreeMusic
+#define sdlh_Mix_HaltChannel                stub_Mix_HaltChannel
+#define sdlh_Mix_HaltMusic                  stub_Mix_HaltMusic
+#define sdlh_Mix_LoadMUS                    stub_Mix_LoadMUS
+#define sdlh_Mix_LoadWAV_RW                 stub_Mix_LoadWAV_RW
+#define sdlh_Mix_OpenAudio                  stub_Mix_OpenAudio
+#define sdlh_Mix_PauseMusic                 stub_Mix_PauseMusic
+#define sdlh_Mix_PlayChannelTimed           stub_Mix_PlayChannelTimed
+#define sdlh_Mix_Playing                    stub_Mix_Playing
+#define sdlh_Mix_ResumeMusic                stub_Mix_ResumeMusic
+#define sdlh_Mix_Volume                     stub_Mix_Volume
+#define sdlh_Mix_VolumeMusic                stub_Mix_VolumeMusic
+#endif
+
+#define sdlh_SDL_ConvertSurface             SDL_ConvertSurface
+#define sdlh_SDL_CreateRGBSurface           SDL_CreateRGBSurface
+#define sdlh_SDL_CreateThread               SDL_CreateThread
+#define sdlh_SDL_Delay                      SDL_Delay
+#define sdlh_SDL_EnableKeyRepeat            SDL_EnableKeyRepeat
+#define sdlh_SDL_EnableUNICODE              SDL_EnableUNICODE
+#define sdlh_SDL_FillRect                   SDL_FillRect
+#define sdlh_SDL_FreeSurface                SDL_FreeSurface
+#define sdlh_SDL_GetError                   SDL_GetError
+#define sdlh_SDL_GetKeyName                 SDL_GetKeyName
+#define sdlh_SDL_GetKeyState                SDL_GetKeyState
+#define sdlh_SDL_GetMouseState              SDL_GetMouseState
+#define sdlh_SDL_GetRGBA                    SDL_GetRGBA
+#define sdlh_SDL_GetTicks                   SDL_GetTicks
+#define sdlh_SDL_GL_SetAttribute            SDL_GL_SetAttribute
+#define sdlh_SDL_GL_SwapBuffers             SDL_GL_SwapBuffers
+#define sdlh_SDL_Init                       SDL_Init
+#define sdlh_SDL_InitSubSystem              SDL_InitSubSystem
+#define sdlh_SDL_JoystickClose              SDL_JoystickClose
+#define sdlh_SDL_JoystickEventState         SDL_JoystickEventState
+#define sdlh_SDL_JoystickName               SDL_JoystickName
+#define sdlh_SDL_JoystickNumAxes            SDL_JoystickNumAxes
+#define sdlh_SDL_JoystickNumButtons         SDL_JoystickNumButtons
+#define sdlh_SDL_JoystickNumHats            SDL_JoystickNumHats
+#define sdlh_SDL_JoystickOpen               SDL_JoystickOpen
+#define sdlh_SDL_LockSurface                SDL_LockSurface
+#define sdlh_SDL_MapRGB                     SDL_MapRGB
+#define sdlh_SDL_MapRGBA                    SDL_MapRGBA
+#define sdlh_SDL_NumJoysticks               SDL_NumJoysticks
+#define sdlh_SDL_PeepEvents                 SDL_PeepEvents
+#define sdlh_SDL_PumpEvents                 SDL_PumpEvents
+#define sdlh_SDL_Quit                       SDL_Quit
+#define sdlh_SDL_RWFromFile                 SDL_RWFromFile
+#define sdlh_SDL_SetColorKey                SDL_SetColorKey
+#define sdlh_SDL_SetVideoMode               SDL_SetVideoMode
+#ifndef EMSCRIPTEN
+#define sdlh_SDL_ShowCursor                 SDL_ShowCursor
+#else
+#define sdlh_SDL_ShowCursor                 SDL_ShowCursor_patch
+#endif
+#define sdlh_SDL_UnlockSurface              SDL_UnlockSurface
+#define sdlh_SDL_UpperBlit                  SDL_UpperBlit
+#define sdlh_SDL_VideoDriverName            SDL_VideoDriverName
+#define sdlh_SDL_WarpMouse                  SDL_WarpMouse
+#define sdlh_SDL_WM_SetCaption              SDL_WM_SetCaption
+#define sdlh_SDL_WM_SetIcon                 SDL_WM_SetIcon
+#define sdlh_SDLNet_AddSocket               SDLNet_AddSocket
+#define sdlh_SDLNet_AllocSocketSet          SDLNet_AllocSocketSet
+#define sdlh_SDLNet_CheckSockets            SDLNet_CheckSockets
+#define sdlh_SDLNet_FreeSocketSet           SDLNet_FreeSocketSet
+#define sdlh_SDLNet_Init                    SDLNet_Init
+#define sdlh_SDLNet_Quit                    SDLNet_Quit
+#define sdlh_SDLNet_ResolveHost             SDLNet_ResolveHost
+#define sdlh_SDLNet_TCP_Close               SDLNet_TCP_Close
+#define sdlh_SDLNet_TCP_Open                SDLNet_TCP_Open
+#define sdlh_SDLNet_TCP_Recv                SDLNet_TCP_Recv
+#define sdlh_SDLNet_TCP_Send                SDLNet_TCP_Send
+#define sdlh_TTF_Init                       TTF_Init
+#define sdlh_TTF_OpenFont                   TTF_OpenFont
+#define sdlh_TTF_Quit                       TTF_Quit
+#define sdlh_TTF_RenderUTF8_Blended         TTF_RenderUTF8_Blended
+#define sdlh_TTF_RenderUTF8_Solid           TTF_RenderUTF8_Solid
+#define sdlh_TTF_SetFontStyle               TTF_SetFontStyle
+#define sdlh_TTF_SizeUTF8                   TTF_SizeUTF8
+
+#define _strconcat                          fpcrtl_strconcat
+#define _strappend                          fpcrtl_strappend
+#define _strprepend                         fpcrtl_strprepend
+#define _strcompare                         fpcrtl_strcompare
+#define _strncompare                        fpcrtl_strncompare
+#define _strcomparec                        fpcrtl_strcomparec
+#define _chrconcat                          fpcrtl_chrconcat
+#define _pchar                              fpcrtl_pchar
+
+// hooks are implemented in javascript
+void start_hook(void);
+void mainloop_hook(void);
+void clear_filelist_hook(void);
+void add_file_hook(const char* ptr);
+void idb_loader_hook();
+void showcursor_hook();
+void hidecursor_hook();
+void drawworld_init_hook();
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/misc.c	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,168 @@
+#include "misc.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <assert.h>
+
+char strbuf[512];
+
+void fpcrtl_assert(int i)
+{
+    if(!i){
+        assert(0);
+    }
+}
+
+// EFFECTS: return the nearest integer of the given number
+int fpcrtl_round(double number)
+{
+    return (number >= 0) ? (int)(number + 0.5) : (int)(number - 0.5);
+}
+
+void fpcrtl_printf(const char* format, ...)
+{
+#ifdef FPCRTL_DEBUG
+    va_list args;
+    va_start (args, format);
+    vprintf (format, args);
+    va_end (args);
+#endif
+}
+
+//
+//void fpcrtl_check_string(string255 str)
+//{
+//#ifdef FPCRTL_DEBUG
+//    int len = strlen(str.str);
+//    if(len != str.len){
+//        printf("String %s internal inconsistency error. Length should be %d but actually is %d.\n", str.str, len, str.len);
+//    }
+//    //assert(len == str.len);
+//#endif
+//}
+
+string255 fpcrtl_strconcat(string255 str1, string255 str2)
+{
+    //printf("str1 = %d, %d\n", str1.len, strlen(str1.str));
+    //printf("str2 = %d, %d\n", str2.len, strlen(str2.str));
+
+#ifdef FPCRTL_DEBUG
+    if(str1.len + (int)(str2.len) > 255){
+        printf("String overflow\n");
+        printf("str1(%d): %s\nstr2(%d): %s\n", str1.len, str1.str, str2.len, str2.str);
+        printf("String will be truncated.\n");
+
+        strbuf[0] = 0;
+        strcpy(strbuf, str1.str);
+        strcat(strbuf, str2.str);
+        memcpy(str1.str, strbuf, 255);
+        str1.str[254] = 0;
+
+        return str1;
+    }
+#endif
+
+    memcpy(&(str1.str[str1.len]), str2.str, str2.len);
+    str1.str[str1.len + str2.len] = 0;
+    str1.len += str2.len;
+
+    return str1;
+}
+
+string255 fpcrtl_strappend(string255 s, char c)
+{
+    s.str[s.len] = c;
+    s.str[s.len + 1] = 0;
+    s.len ++;
+
+    return s;
+}
+
+string255 fpcrtl_strprepend(char c, string255 s)
+{
+    FIX_STRING(s);
+
+    memmove(s.str + 1, s.str, s.len + 1); // also move '/0'
+    s.str[0] = c;
+    s.len++;
+
+    return s;
+}
+
+string255 fpcrtl_chrconcat(char a, char b)
+{
+    string255 result;
+
+    result.len = 2;
+    result.str[0] = a;
+    result.str[1] = b;
+    result.str[2] = 0;
+
+    return result;
+}
+
+bool fpcrtl_strcompare(string255 str1, string255 str2)
+{
+    //printf("str1 = %d, %d\n", str1.len, strlen(str1.str));
+    //printf("str2 = %d, %d\n", str2.len, strlen(str2.str));
+    FIX_STRING(str1);
+    FIX_STRING(str2);
+
+    if(strcmp(str1.str, str2.str) == 0){
+        return true;
+    }
+
+    return false;
+}
+
+bool fpcrtl_strcomparec(string255 a, char b)
+{
+    FIX_STRING(a);
+
+    if(a.len == 1 && a.str[0] == b){
+        return true;
+    }
+
+    return false;
+}
+
+bool fpcrtl_strncompare(string255 a, string255 b)
+{
+    return !fpcrtl_strcompare(a, b);
+}
+
+//char* fpcrtl_pchar(string255 s)
+//{
+//    return s.str;
+//}
+
+string255 fpcrtl_pchar2str(char *s)
+{
+    string255 result;
+    int t = strlen(s);
+
+    if(t > 255){
+        printf("pchar2str, length > 255\n");
+        assert(0);
+    }
+
+    result.len = t;
+    memcpy(result.str, s, t);
+    result.str[t] = 0;
+
+    return result;
+}
+
+string255 fpcrtl_make_string(const char* s) {
+    string255 result;
+    strcpy(result.str, s);
+    result.len = strlen(s);
+    return result;
+}
+
+#ifdef EMSCRIPTEN
+GLenum glewInit()
+{
+    return GLEW_OK;
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/misc.h	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,58 @@
+#ifndef _FPCRTL_MISC_H_
+#define _FPCRTL_MISC_H_
+
+#include "pas2c.h"
+#include <assert.h>
+#include <stdbool.h>
+
+#ifdef EMSCRIPTEN
+#include <GL/gl.h>
+#else
+#include <GL/glew.h>
+#endif
+
+#define     VA_NUM_ARGS(...)                        VA_NUM_ARGS_IMPL(__VA_ARGS__, 5,4,3,2,1)
+#define     VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,N,...)  N
+
+#define     macro_dispatcher(func, ...)             macro_dispatcher_(func, VA_NUM_ARGS(__VA_ARGS__))
+#define     macro_dispatcher_(func, nargs)          macro_dispatcher__(func, nargs)
+#define     macro_dispatcher__(func, nargs)         func ## nargs
+
+#define     FPCRTL_DEBUG
+
+#define     FIX_STRING(s)                           (s.str[s.len] = 0)
+
+//#define fpcrtl_check_string(s)     do{ if(strlen((s).str) != (s).len){ \
+//                                        printf("String %s internal inconsistency error. Length should be %d but actually is %d.\n", (s).str, strlen((s).str), (s).len); \
+//                                        assert(0);\
+//                                    }}while(0)
+
+void        fpcrtl_assert(int);
+void        fpcrtl_print_trace (void);
+
+int         fpcrtl_round(double number);
+void        fpcrtl_printf(const char* format, ...);
+
+string255   fpcrtl_make_string(const char* s);
+
+string255   fpcrtl_strconcat(string255 str1, string255 str2);
+string255   fpcrtl_strappend(string255 s, char c);
+string255   fpcrtl_strprepend(char c, string255 s);
+string255   fpcrtl_chrconcat(char a, char b);
+
+// return true if str1 == str2
+bool        fpcrtl_strcompare(string255 str1, string255 str2);
+bool        fpcrtl_strcomparec(string255 a, char b);
+bool        fpcrtl_strncompare(string255 a, string255 b);
+
+#define     fpcrtl__pchar(s)                        ((s).str)
+string255   fpcrtl_pchar2str(char *s);
+
+#define     fpcrtl_TypeInfo                         sizeof // dummy
+
+#ifdef EMSCRIPTEN
+#define     GLEW_OK                                 1
+GLenum      glewInit();
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/pas2c.h	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,80 @@
+#pragma once
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <wchar.h>
+#include <math.h>
+
+#define MAX_PARAMS 64
+
+typedef union string255_
+    {
+        struct {
+            char s[257];
+        };
+        struct {
+            unsigned char len;
+            char str[256];
+        };
+    } string255;
+typedef struct string192_
+    {
+        char s[193];
+    } string192;
+typedef struct string31_
+    {
+        char s[32];
+    } string31;
+typedef struct string15_
+    {
+        char s[16];
+    } string15;
+
+typedef string255 shortstring;
+typedef string255 ansistring;
+
+typedef uint8_t Byte;
+typedef int8_t ShortInt;
+typedef uint16_t Word;
+typedef int16_t SmallInt;
+typedef uint32_t LongWord;
+typedef int32_t LongInt;
+typedef uint64_t QWord;
+typedef int64_t Int64;
+typedef LongWord Cardinal;
+
+typedef LongInt Integer;
+typedef float extended;
+typedef float real;
+typedef float single;
+
+typedef bool boolean;
+typedef int LongBool;
+
+typedef void * pointer;
+typedef Byte * PByte;
+typedef char * PChar;
+typedef LongInt * PLongInt;
+typedef LongWord * PLongWord;
+typedef Integer * PInteger;
+typedef int PtrInt;
+typedef wchar_t widechar;
+typedef wchar_t* PWideChar;
+typedef char Char;
+typedef LongInt SizeInt;
+typedef char ** PPChar;
+typedef Word* PWord;
+
+string255 _strconcat(string255 a, string255 b);
+string255 _strappend(string255 s, char c);
+string255 _strprepend(char c, string255 s);
+string255 _chrconcat(char a, char b);
+bool _strcompare(string255 a, string255 b);
+bool _strcomparec(string255 a, char b);
+bool _strncompare(string255 a, string255 b);
+
+
+#define STRINIT(a) {.len = sizeof(a) - 1, .str = a}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/pmath.c	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,49 @@
+#include "pmath.h"
+#include <stdlib.h>
+#include <math.h>
+
+/*
+ * power raises base to the power power.
+ * This is equivalent to exp(power*ln(base)). Therefore base should be non-negative.
+ */
+float fpcrtl_power(float base, float exponent)
+{
+    return exp(exponent * log(base));
+}
+
+/* Currently the games only uses sign of an integer */
+int fpcrtl_signi(int x)
+{
+    if(x > 0){
+        return 1;
+    }
+    else if(x < 0){
+        return -1;
+    }
+    else{
+        return 0;
+    }
+}
+
+float fpcrtl_csc(float x)
+{
+    return 1 / sin(x);
+}
+
+float __attribute__((overloadable)) fpcrtl_abs(float x)
+{
+    return fabs(x);
+}
+double __attribute__((overloadable)) fpcrtl_abs(double x)
+{
+    return fabs(x);
+}
+int __attribute__((overloadable)) fpcrtl_abs(int x)
+{
+    return abs(x);
+}
+
+int64_t __attribute__((overloadable)) fpcrtl_abs(int64_t x)
+{
+    return x < 0 ? -x : x;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/pmath.h	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,24 @@
+#ifndef PMATH_H_
+#define PMATH_H_
+
+#include <stdint.h>
+#include <math.h>
+
+#define     fpcrtl_min(a, b)                ((a) < (b) ? (a) : (b))
+#define     fpcrtl_max(a, b)                ((a) > (b) ? (a) : (b))
+
+float       fpcrtl_power(float base, float exponent);
+
+/* Currently the games only uses sign of an integer */
+int         fpcrtl_signi(int x);
+
+float       fpcrtl_csc(float x);
+
+#define     fpcrtl_arctan2(y, x)            atan2(y, x)
+
+float       __attribute__((overloadable))   fpcrtl_abs(float x);
+double      __attribute__((overloadable))   fpcrtl_abs(double x);
+int         __attribute__((overloadable))   fpcrtl_abs(int x);
+int64_t     __attribute__((overloadable))   fpcrtl_abs(int64_t x);
+
+#endif /* PMATH_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/system.c	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,282 @@
+#include "system.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <wchar.h>
+
+#ifndef M_PI
+// some math.h do not have M_PI macros
+# define M_PI    3.14159265358979323846  /* pi */
+# define M_PI_2  1.57079632679489661923  /* pi/2 */
+# define M_PI_4  0.78539816339744830962  /* pi/4 */
+# define M_PIl   3.1415926535897932384626433832795029L  /* pi */
+# define M_PI_2l 1.5707963267948966192313216916397514L  /* pi/2 */
+# define M_PI_4l 0.7853981633974483096156608458198757L  /* pi/4 */
+#endif
+
+double pi = M_PI;
+
+int paramCount;
+string255 params[MAX_PARAMS];
+
+string255 fpcrtl_copy(string255 s, Integer index, Integer count) {
+    string255 result = STRINIT("");
+
+    if (count < 1) {
+        return result;
+    }
+
+    if (index < 1) {
+        index = 1;
+    }
+
+    if (index > s.len) {
+        return result;
+    }
+
+    if (index + count > s.len + 1) {
+        count = s.len + 1 - index;
+    }
+
+    memcpy(result.str, s.str + index - 1, count);
+
+    result.str[count] = 0;
+    result.len = count;
+
+    return result;
+}
+
+void fpcrtl_delete__vars(string255 *s, SizeInt index, SizeInt count) {
+    // number of chars to be move
+    int num_move;
+    int new_length;
+
+    string255 temp = *s;
+
+    if (index < 1) {
+        // in fpc, if index < 1, the string won't be modified
+        return;
+    }
+
+    if(index > s->len){
+        return;
+    }
+
+    if (count > s->len - index + 1) {
+        s->str[index - 1] = 0;
+        s->len = index - 1;
+        return;
+    }
+
+    num_move = s->len - index + 1 - count;
+    new_length = s->len - count;
+
+    memmove(s->str + index - 1, temp.str + index - 1 + count, num_move);
+    s->str[new_length] = 0;
+
+    s->len = new_length;
+
+}
+
+string255 fpcrtl_floatToStr(double n) {
+    string255 t;
+    sprintf(t.str, "%f", n);
+    t.len = strlen(t.str);
+
+    return t;
+}
+
+void fpcrtl_move__vars(void *src, void *dst, SizeInt count) {
+    memmove(dst, src, count);
+}
+
+Integer __attribute__((overloadable)) fpcrtl_pos(Char c, string255 str) {
+    string255 t;
+    t.len = 1;
+    t.str[0] = c;
+    t.str[1] = 0;
+    return fpcrtl_pos(t, str);
+}
+
+Integer __attribute__((overloadable)) fpcrtl_pos(string255 substr, string255 str) {
+
+    char* p;
+
+    FIX_STRING(substr);
+    FIX_STRING(str);
+
+    if (str.len == 0) {
+        return 0;
+    }
+
+    if (substr.len == 0) {
+        return 0;
+    }
+
+    str.str[str.len] = 0;
+    substr.str[substr.len] = 0;
+
+    p = strstr(str.str, substr.str);
+
+    if (p == NULL) {
+        return 0;
+    }
+
+    return strlen(str.str) - strlen(p) + 1;
+}
+
+Integer fpcrtl_length(string255 s) {
+    return s.len;
+}
+
+string255 fpcrtl_lowerCase(string255 s) {
+    int i;
+
+    for (i = 0; i < s.len; i++) {
+        if (s.str[i] >= 'A' && s.str[i] <= 'Z') {
+            s.str[i] += 'a' - 'A';
+        }
+    }
+
+    return s;
+}
+
+void fpcrtl_fillChar__vars(void *x, SizeInt count, Byte value) {
+    memset(x, value, count);
+}
+
+void fpcrtl_new__vars(void **p, int size) {
+    *p = malloc(size);
+}
+
+Integer fpcrtl_trunc(extended n) {
+    return (int) n;
+}
+
+LongInt str_to_int(char *src)
+{
+    int i;
+    int len = strlen(src);
+    char *end;
+    for(i = 0; i < len; i++)
+    {
+        if(src[i] == '$'){
+            // hex
+            return strtol(src + i + 1, &end, 16);
+        }
+    }
+
+    // decimal
+    return atoi(src);
+}
+
+void __attribute__((overloadable)) fpcrtl_val__vars(string255 s, LongInt *a)
+{
+    FIX_STRING(s);
+    *a = str_to_int(s.str);
+}
+
+void __attribute__((overloadable)) fpcrtl_val__vars(string255 s, Byte *a)
+{
+    FIX_STRING(s);
+    *a = str_to_int(s.str);
+}
+
+void __attribute__((overloadable)) fpcrtl_val__vars(string255 s, LongWord *a)
+{
+    FIX_STRING(s);
+    *a = str_to_int(s.str);
+}
+
+LongInt fpcrtl_random(LongInt l) {
+    return (LongInt) (rand() / (double) RAND_MAX * l);
+}
+
+void __attribute__((overloadable)) fpcrtl_str__vars(float x, string255 *s) {
+    sprintf(s->str, "%f", x);
+    s->len = strlen(s->str);
+}
+void __attribute__((overloadable)) fpcrtl_str__vars(double x, string255 *s) {
+    sprintf(s->str, "%f", x);
+    s->len = strlen(s->str);
+}
+void __attribute__((overloadable)) fpcrtl_str__vars(uint8_t x, string255 *s) {
+    sprintf(s->str, "%u", x);
+    s->len = strlen(s->str);
+}
+void __attribute__((overloadable)) fpcrtl_str__vars(int8_t x, string255 *s) {
+    sprintf(s->str, "%d", x);
+    s->len = strlen(s->str);
+}
+void __attribute__((overloadable)) fpcrtl_str__vars(uint16_t x, string255 *s) {
+    sprintf(s->str, "%u", x);
+    s->len = strlen(s->str);
+}
+void __attribute__((overloadable)) fpcrtl_str__vars(int16_t x, string255 *s) {
+    sprintf(s->str, "%d", x);
+    s->len = strlen(s->str);
+}
+void __attribute__((overloadable)) fpcrtl_str__vars(uint32_t x, string255 *s) {
+    sprintf(s->str, "%u", x);
+    s->len = strlen(s->str);
+}
+void __attribute__((overloadable)) fpcrtl_str__vars(int32_t x, string255 *s) {
+    sprintf(s->str, "%d", x);
+    s->len = strlen(s->str);
+}
+void __attribute__((overloadable)) fpcrtl_str__vars(uint64_t x, string255 *s) {
+    sprintf(s->str, "%llu", x);
+    s->len = strlen(s->str);
+}
+void __attribute__((overloadable)) fpcrtl_str__vars(int64_t x, string255 *s) {
+    sprintf(s->str, "%lld", x);
+    s->len = strlen(s->str);
+}
+
+/*
+ * XXX No protection currently!
+ */
+void fpcrtl_interlockedIncrement__vars(int *i) {
+    (*i)++;
+}
+
+void fpcrtl_interlockedDecrement__vars(int *i) {
+    (*i)--;
+}
+
+/*
+ * This function should be called when entering main
+ */
+void fpcrtl_init(int argc, char** argv) {
+    int i;
+    paramCount = argc;
+
+    printf("ARGC = %d\n", paramCount);
+
+    for (i = 0; i < argc; i++) {
+        if (strlen(argv[i]) > 255) {
+            assert(0);
+        }
+        strcpy(params[i].str, argv[i]);
+        params[i].len = strlen(params[i].str);
+    }
+
+}
+
+int fpcrtl_paramCount() {
+    return paramCount - 1; // ignore the first one
+}
+
+string255 fpcrtl_paramStr(int i) {
+    return params[i];
+}
+
+int fpcrtl_UTF8ToUnicode(PWideChar dest, PChar src, SizeInt maxLen) {
+    //return swprintf(dest, maxLen, L"%hs", "src"); //doesn't work in emscripten
+    return 0;
+}
+
+uint32_t __attribute__((overloadable)) fpcrtl_lo(uint64_t i) {
+    return (i & 0xFFFFFFFF);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/system.h	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,169 @@
+#ifndef SYSTEM_H_
+#define SYSTEM_H_
+
+#include <time.h>
+#include "Types.h"
+#include "misc.h"
+
+extern double pi;
+
+typedef TDate* PDate;
+
+// dimension info for dynamic arrays
+typedef struct {
+    int dim;
+    int a[4]; // at most 4
+} fpcrtl_dimension_t;
+
+/*
+ * Copy returns a string which is a copy if the Count characters in S, starting at position Index.
+ * If Count is larger than the length of the string S, the result is truncated.
+ * If Index is larger than the length of the string S, then an empty string is returned.
+ * Index is 1-based.
+ */
+string255   fpcrtl_copy(string255 s, Integer Index, Integer Count);
+
+/*
+ * Delete removes Count characters from string S, starting at position Index.
+ * All characters after the deleted characters are shifted Count positions to the left,
+ * and the length of the string is adjusted.
+ */
+#define     fpcrtl_delete(s, index, count)                  fpcrtl_delete__vars(&(s), index, count)
+void        fpcrtl_delete__vars(string255 *s, SizeInt index, SizeInt count);
+
+string255   fpcrtl_floatToStr(double n);
+
+/*
+ * Move data from one location in memory to another
+ */
+void        fpcrtl_move__vars(void *src, void *dst, SizeInt count);
+#define     fpcrtl_move(src, dst, count)                    fpcrtl_move__vars(&(src), &(dst), count);
+#define     fpcrtl_Move                                     fpcrtl_move
+
+Integer     __attribute__((overloadable))                   fpcrtl_pos(Char c, string255 str);
+Integer     __attribute__((overloadable))                   fpcrtl_pos(string255 substr, string255 str);
+
+Integer     fpcrtl_length(string255 s);
+#define     fpcrtl_Length                                   fpcrtl_length
+
+#define     fpcrtl_sqr(x)                                   ((x) * (x))
+
+#define     fpcrtl_odd(x)                                   ((x) % 2 != 0 ? true : false)
+
+#define     fpcrtl_StrLen                                   strlen
+
+#define     SizeOf                                          sizeof
+
+string255   fpcrtl_lowerCase(string255 s);
+#define     fpcrtl_LowerCase                                fpcrtl_lowerCase
+
+void        fpcrtl_fillChar__vars(void *x, SizeInt count, Byte value);
+#define     fpcrtl_fillChar(x, count, value)                fpcrtl_fillChar__vars(&(x), count, value)
+#define     fpcrtl_FillChar                                 fpcrtl_fillChar
+
+void        fpcrtl_new__vars(void **p, int size);
+#define     fpcrtl_new(a)                                   fpcrtl_new__vars((void **)&(a), sizeof(*(a)))
+
+#define     fpcrtl_dispose                                  free
+
+#define     fpcrtl_freeMem(p, size)                         free(p)
+#define     fpcrtl_FreeMem(p, size)                         free(p)
+
+#define     fpcrtl_getMem(size)                             malloc(size)
+#define     fpcrtl_GetMem                                   fpcrtl_getMem
+
+#define     fpcrtl_assigned(p)                              ((p) != NULL)
+#define     fpcrtl_Assigned                                 fpcrtl_assigned
+
+Integer     fpcrtl_trunc(extended n);
+
+#define     fpcrtl_val(s, a)                                fpcrtl_val__vars(s, &(a))
+void        __attribute__((overloadable))                   fpcrtl_val__vars(string255 s, LongInt *a);
+void        __attribute__((overloadable))                   fpcrtl_val__vars(string255 s, Byte *a);
+void        __attribute__((overloadable))                   fpcrtl_val__vars(string255 s, LongWord *a);
+
+#define     fpcrtl_randomize()                              srand(time(NULL))
+
+/*
+ * Random returns a random number larger or equal to 0 and strictly less than L
+ */
+LongInt     fpcrtl_random(LongInt l);
+
+string255   fpcrtl_paramStr(LongInt);
+#define     fpcrtl_ParamStr                                 fpcrtl_paramStr
+
+/*
+ * Str returns a string which represents the value of X. X can be any numerical type.
+ */
+#define     fpcrtl_str(x, s)                                fpcrtl_str__vars(x, &(s))
+void        __attribute__((overloadable))                   fpcrtl_str__vars(float x, string255 *s);
+void        __attribute__((overloadable))                   fpcrtl_str__vars(double x, string255 *s);
+void        __attribute__((overloadable))                   fpcrtl_str__vars(uint8_t x, string255 *s);
+void        __attribute__((overloadable))                   fpcrtl_str__vars(int8_t x, string255 *s);
+void        __attribute__((overloadable))                   fpcrtl_str__vars(uint16_t x, string255 *s);
+void        __attribute__((overloadable))                   fpcrtl_str__vars(int16_t x, string255 *s);
+void        __attribute__((overloadable))                   fpcrtl_str__vars(uint32_t x, string255 *s);
+void        __attribute__((overloadable))                   fpcrtl_str__vars(int32_t x, string255 *s);
+void        __attribute__((overloadable))                   fpcrtl_str__vars(uint64_t x, string255 *s);
+void        __attribute__((overloadable))                   fpcrtl_str__vars(int64_t x, string255 *s);
+
+void        fpcrtl_interlockedIncrement__vars(int *i);
+void        fpcrtl_interlockedDecrement__vars(int *i);
+
+#define     fpcrtl_interlockedIncrement(i)                  fpcrtl_interlockedIncrement__vars(&(i))
+#define     fpcrtl_interlockedDecrement(i)                  fpcrtl_interlockedDecrement__vars(&(i))
+
+#define     fpcrtl_InterlockedIncrement                     fpcrtl_interlockedIncrement
+#define     fpcrtl_InterlockedDecrement                     fpcrtl_interlockedDecrement
+
+void        fpcrtl_init(int argc, char** argv);
+
+int         fpcrtl_paramCount();
+#define     fpcrtl_ParamCount                               fpcrtl_paramCount
+
+string255   fpcrtl_paramStr(int i);
+#define     fpcrtl_ParamStr                                 fpcrtl_paramStr
+
+int         fpcrtl_UTF8ToUnicode(PWideChar dest, PChar src, SizeInt maxLen);
+
+#define     fpcrtl_halt(t)                                  assert(0)
+
+#define     fpcrtl_Load_GL_VERSION_2_0()                    1
+
+uint32_t    __attribute__((overloadable))                   fpcrtl_lo(uint64_t);
+#define     fpcrtl_Lo                                       fpcrtl_lo
+
+#define     __SET_LENGTH2(arr, d, b) do{\
+                d.dim = 1;\
+                arr = realloc(arr, b * sizeof(typeof(*arr)));\
+                d.a[0] = b;\
+            }while(0)
+
+#define     SET_LENGTH2(arr, b)                             __SET_LENGTH2(arr, arr##_dimension_info, (b))
+
+#define     __SET_LENGTH3(arr, d, b, c) do{\
+                d.dim = 2;\
+                for (int i = 0; i < d.a[0]; i++) {\
+                    arr[i] = realloc(arr[i], c * sizeof(typeof(**arr)));\
+                }\
+                if (d.a[0] > b) {\
+                    for (int i = b; i < d.a[0]; i++) {\
+                        free(arr[i]);\
+                    }\
+                    arr = realloc(arr, b * sizeof(typeof(*arr)));\
+                } else if (d.a[0] < b) {\
+                    arr = realloc(arr, b * sizeof(typeof(*arr)));\
+                    for (int i = d.a[0]; i < b; i++) {\
+                        arr[i] = malloc(c * sizeof(typeof(**arr)));\
+                        memset(arr[i], 0, c * sizeof(typeof(**arr)));\
+                    }\
+                }\
+                d.a[0] = b;\
+                d.a[1] = c;\
+            }while(0)
+
+#define     SET_LENGTH3(arr, b, c)                          __SET_LENGTH3(arr, arr##_dimension_info, (b), (c))
+
+#define     fpcrtl_SetLength(...)                           macro_dispatcher(SET_LENGTH, __VA_ARGS__)(__VA_ARGS__)
+
+#endif /* SYSTEM_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/sysutils.c	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,178 @@
+#include "SysUtils.h"
+
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "system.h"
+#include "misc.h"
+
+TDateTime fpcrtl_date()
+{
+    const int num_days_between_1900_1980 = 29220;
+
+    struct tm ref_date;
+    struct tm cur_date;
+    time_t local_time;
+    time_t ref_time, cur_time;
+
+    double timeDiff;
+    double day_time_frac; //fraction that represents the time in one day
+    int num_seconds;
+    int numDays;
+    
+    // unix epoch doesn't work, choose Jan 1st 1980 instead
+    ref_date.tm_year = 80;
+    ref_date.tm_mon = 0;
+    ref_date.tm_mday = 1;
+    ref_date.tm_hour = 0;
+    ref_date.tm_min = 0;
+    ref_date.tm_sec = 0;
+    ref_date.tm_isdst = 0;
+    ref_date.tm_wday = 0; // ignored
+    ref_date.tm_yday = 0; // ignored
+
+    local_time = time(NULL);
+    cur_date = *localtime(&local_time);
+
+    cur_date.tm_hour = 0;
+    cur_date.tm_min = 0;
+    cur_date.tm_sec = 0;
+
+    ref_time = mktime(&ref_date);
+    cur_time = mktime(&cur_date);
+
+    timeDiff = difftime(cur_time, ref_time);
+    numDays = fpcrtl_round(timeDiff / 3600 / 24) + num_days_between_1900_1980 + 1;
+
+    fpcrtl_printf("[date] tim diff: %f\n", timeDiff);
+    fpcrtl_printf("[date] num days between 1980 and today:  %d\n", fpcrtl_round(timeDiff/3600/24));
+    fpcrtl_printf("[date] current date: %s\n", asctime(&cur_date));
+    fpcrtl_printf("[date] reference date: %s\n", asctime(&ref_date));
+    fpcrtl_printf("[date] num days: %d\n", numDays);
+    
+    return numDays;
+}
+
+TDateTime fpcrtl_time()
+{
+    struct tm cur_date;
+    time_t local_time;
+    time_t cur_time;
+
+    double day_time_frac; //fraction that represents the time in one day
+    int num_seconds;
+    
+    local_time = time(NULL);
+    cur_date = *localtime(&local_time);
+
+    num_seconds = cur_date.tm_hour * 3600 + cur_date.tm_min * 60 + cur_date.tm_sec;
+    day_time_frac = num_seconds / 3600.0 / 24.0;
+
+    fpcrtl_printf("%f\n", day_time_frac);
+
+    return day_time_frac;
+}
+
+TDateTime fpcrtl_now()
+{
+    return fpcrtl_date() + fpcrtl_time();
+}
+
+/*
+ * XXX: dummy
+ */
+string255 fpcrtl_formatDateTime(string255 FormatStr, TDateTime DateTime)
+{
+    string255 result = STRINIT("2012 01-01");
+    return result;
+}
+
+string255 fpcrtl_trim(string255 s)
+{
+    int left, right;
+
+    if(s.len == 0){
+        return s;
+    }
+
+    for(left = 0; left < s.len; left++)
+    {
+        if(s.str[left] != ' '){
+            break;
+        }
+    }
+
+    for(right = s.len - 1; right >= 0; right--)
+    {
+        if(s.str[right] != ' '){
+            break;
+        }
+    }
+
+    if(left > right){
+        s.len = 0;
+        s.str[0] = 0;
+        return s;
+    }
+
+    s.len = right - left + 1;
+    memmove(s.str, s.str + left, s.len);
+
+    s.str[s.len] = 0;
+
+    return s;
+}
+
+Integer fpcrtl_strToInt(string255 s)
+{
+    s.str[s.len] = 0;
+    return atoi(s.str);
+}
+
+//function ExtractFileName(const FileName: string): string;
+//var
+//  i : longint;
+//  EndSep : Set of Char;
+//begin
+//  I := Length(FileName);
+//  EndSep:=AllowDirectorySeparators+AllowDriveSeparators;
+//  while (I > 0) and not (FileName[I] in EndSep) do
+//    Dec(I);
+//  Result := Copy(FileName, I + 1, MaxInt);
+//end;
+
+string255 fpcrtl_extractFileName(string255 f)
+{
+    const char sep[] = {'\\', '/', ':'};
+    LongInt i,j;
+
+    i = f.len - 1;
+    while(i >= 0){
+        for(j = 0; j < sizeof(sep); j++){
+            if(f.str[i] == sep[j]){
+                goto FPCRTL_EXTRACTFILENAME_END;
+            }
+        }
+        i--;
+    }
+FPCRTL_EXTRACTFILENAME_END:
+    return fpcrtl_copy(f, i + 2, 256);
+}
+
+string255 fpcrtl_strPas(PChar p)
+{
+    string255 s;
+    int l = strlen(p);
+
+    if(l > 255){
+        printf("strPas: source string length > 255\n");
+        assert(0);
+    }
+
+    s.len = l;
+    strcpy(s.str, p);
+
+    return s;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/tests/check_check.c	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,23 @@
+#include <check.h>
+#include <stdlib.h>
+#include "check_check.h"
+
+int main(void)
+{
+	int number_failed;
+
+	Suite *s1 = system_suite();
+	Suite *s2 = misc_suite();
+	Suite *s3 = sysutils_suite();
+	Suite *s4 = fileio_suite();
+
+	SRunner *sr = srunner_create(s1);
+	srunner_add_suite(sr, s2);
+	srunner_add_suite(sr, s3);
+	srunner_add_suite(sr, s4);
+
+	srunner_run_all(sr, CK_NORMAL);
+	number_failed = srunner_ntests_failed(sr);
+	srunner_free(sr);
+	return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/tests/check_check.h	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,9 @@
+#ifndef _CHECK_CHECK_H_
+#define _CHECK_CHECK_H_
+
+Suite *system_suite();
+Suite *misc_suite();
+Suite *sysutils_suite();
+Suite *fileio_suite();
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/tests/check_fileio.c	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,103 @@
+#include <check.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "check_check.h"
+#include "../src/fpcrtl.h"
+
+typedef struct __TResourceList
+{
+	Integer count;
+	string255 files[500 + 1];
+} TResourceList;
+
+string255 t = STRINIT("test");
+string255 Pathz[1] =
+{ STRINIT("../../") };
+int ptCurrTheme = 0;
+string255 cThemeCFGFilename = STRINIT("theme.cfg");
+const string255 __str79 = STRINIT("object");
+string255 c1 = STRINIT("=");
+string255 c2 = STRINIT("\x2c");
+string255 c3 = STRINIT("\x2f");
+
+static string255 make_string(const char* str)
+{
+	string255 s;
+	s.len = strlen(str);
+	memcpy(s.str, str, s.len + 1);
+	return s;
+}
+
+TResourceList readThemeCfg_0()
+{
+	TResourceList readthemecfg_result;
+	string255 s;
+	string255 key;
+	TextFile f;
+	Integer i;
+	TResourceList res;
+
+	s = _strconcat(_strappend(Pathz[ptCurrTheme], '\x2f'), cThemeCFGFilename);
+	//umisc_log(s);
+
+	fpcrtl_assign(f, s);
+
+	FileMode = 0;
+	fpcrtl_reset(f);
+
+	res.count = 0;
+	while (!(fpcrtl_eof(f)))
+	{
+		fpcrtl_readLnS(f, s);
+		if ((fpcrtl_Length(s)) == (0))
+		{
+			continue;
+		}
+		if ((s.s[1]) == ('\x3b'))
+		{
+			continue;
+		}
+		i = fpcrtl_pos('\x3d', s);
+		key = fpcrtl_trim(fpcrtl_copy(s, 1, i - 1));
+		fpcrtl_delete(s, 1, i);
+		if (_strcompare(key, __str79))
+		{
+			i = fpcrtl_pos('\x2c', s);
+			res.files[res.count] = _strconcat(
+					_strappend(Pathz[ptCurrTheme], '\x2f'),
+					fpcrtl_trim(fpcrtl_copy(s, 1, i - 1)));
+			++res.count;
+			//umisc_log(fpcrtl_trim(fpcrtl_copy(s, 1, i - 1)));
+		}
+	}
+	fpcrtl_close(f);
+	readthemecfg_result = res;
+	return readthemecfg_result;
+}
+
+START_TEST(test_readthemecfg)
+	{
+		int i;
+		TResourceList result;
+
+		printf("-----Entering test readthemecfg-----\n");
+		result = readThemeCfg_0();
+		for (i = 0; i < result.count; i++)
+		{
+			printf("%s\n", result.files[i].str);
+		}
+		printf("-----Leaving test readthemecfg-----\n");
+	}END_TEST
+
+Suite* fileio_suite(void)
+{
+	Suite *s = suite_create("fileio");
+
+	TCase *tc_core = tcase_create("Core");
+
+	tcase_add_test(tc_core, test_readthemecfg);
+
+	suite_add_tcase(s, tc_core);
+
+	return s;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/tests/check_misc.c	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,88 @@
+#include <check.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "check_check.h"
+#include "../src/misc.h"
+
+static string255 make_string(const char* str)
+{
+	string255 s;
+	s.len = strlen(str);
+	memcpy(s.str, str, s.len + 1);
+	return s;
+}
+
+START_TEST(test_strconcat)
+{
+	string255 t;
+	t = fpcrtl_strconcat(make_string(""), make_string(""));
+	fail_if(strcmp(t.str, ""), "strconcat(\"\", \"\")");
+
+	t = fpcrtl_strconcat(make_string(""), make_string("a"));
+	fail_if(strcmp(t.str, "a"), "strconcat(\"\", \"a\")");
+
+	t = fpcrtl_strconcat(make_string("a"), make_string(""));
+	fail_if(strcmp(t.str, "a"), "strconcat(\"a\", \"\")");
+
+	t = fpcrtl_strconcat(make_string("ab"), make_string(""));
+	fail_if(strcmp(t.str, "ab"), "strconcat(\"ab\", \"\")");
+
+	t = fpcrtl_strconcat(make_string("ab"), make_string("cd"));
+	fail_if(strcmp(t.str, "abcd"), "strconcat(\"ab\", \"cd\")");
+}
+END_TEST
+
+START_TEST (test_strappend)
+{
+	string255 t;
+
+	t = fpcrtl_strappend(make_string(""), 'c');
+	fail_if(strcmp(t.str, "c"), "strappend(\"\", 'c')");
+
+	t = fpcrtl_strappend(make_string("ab"), 'c');
+	fail_if(strcmp(t.str, "abc"), "strappend(\"ab\", 'c')");
+}
+END_TEST
+
+START_TEST (test_strprepend)
+{
+	string255 t;
+
+	t = fpcrtl_strprepend('c', make_string(""));
+	fail_if(strcmp(t.str, "c"), "strprepend('c', \"\")");
+
+	t = fpcrtl_strprepend('c', make_string("ab"));
+	fail_if(strcmp(t.str, "cab"), "strprepend('c', \"ab\")");
+}
+END_TEST
+
+START_TEST (test_strcompare)
+{
+	fail_unless(fpcrtl_strcompare(make_string(""), make_string("")), "strcompare(\"\", \"\")");
+	fail_unless(fpcrtl_strcompare(make_string("a"), make_string("a")), "strcompare(\"a\", \"a\"");
+	fail_unless(!fpcrtl_strcompare(make_string("a"), make_string("b")), "strcompare(\"a\", \"b\")");
+	fail_unless(!fpcrtl_strcompare(make_string("a"), make_string("ab")), "strcompare(\"a\", \"ab\")");
+
+	fail_unless(fpcrtl_strcomparec(make_string(" "), ' '), "strcomparec(\" \", ' ')");
+	fail_unless(fpcrtl_strcomparec(make_string("a"), 'a'), "strcomparec(\"a\", 'a')");
+	fail_unless(!fpcrtl_strcomparec(make_string("  "), ' '), "strcomparec(\"  \", ' '");
+	fail_unless(!fpcrtl_strcomparec(make_string(""), ' '), "strcomparec(\"\", ' ')");
+
+}
+END_TEST
+
+Suite* misc_suite(void)
+{
+	Suite *s = suite_create("misc");
+
+	TCase *tc_core = tcase_create("Core");
+
+	tcase_add_test(tc_core, test_strconcat);
+	tcase_add_test(tc_core, test_strappend);
+	tcase_add_test(tc_core, test_strprepend);
+	tcase_add_test(tc_core, test_strcompare);
+
+	suite_add_tcase(s, tc_core);
+
+	return s;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/tests/check_system.c	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,251 @@
+#include <check.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "check_check.h"
+#include "../src/system.h"
+
+void check_string(string255 str)
+{
+	fail_unless(strlen(str.str) == str.len, "String internal inconsistency error");
+}
+
+static string255 make_string(const char* str)
+{
+	string255 s;
+	s.len = strlen(str);
+	memcpy(s.str, str, s.len + 1);
+	return s;
+}
+
+START_TEST (test_copy)
+	{
+		string255 s = STRINIT("1234567");
+		string255 t;
+
+		t = fpcrtl_copy(s, 1, 1);
+		fail_if(strcmp(t.str, "1"), "Test copy fail 1");
+
+		t = fpcrtl_copy(s, 7, 1);
+		fail_if(strcmp(t.str, "7"), "Test copy fail 2");
+
+		t = fpcrtl_copy(s, 8, 1);
+		fail_if(t.len != 0, "Test copy fail 3");
+
+		t = fpcrtl_copy(s, 8, 100);
+		fail_if(t.len != 0, "Test copy fail 4");
+		check_string(t);
+
+		t = fpcrtl_copy(s, 0, 100);
+		fail_if(strcmp(t.str, "1234567"), "Test copy fail 5");
+
+		t = fpcrtl_copy(s, 0, 5);
+		fail_if(strcmp(t.str, "12345"), "Test copy fail 6");
+
+		t = fpcrtl_copy(s, 4, 100);
+		fail_if(strcmp(t.str, "4567"), "Test copy fail 7");
+
+		t = fpcrtl_copy(s, 4, 2);
+		fail_if(strcmp(t.str, "45"), "Test copy fail 8");
+	}END_TEST
+
+START_TEST (test_delete)
+	{
+		string255 s = STRINIT("1234567");
+		string255 s2 = STRINIT("1234567");
+		string255 s3 = STRINIT("1234567");
+
+		fpcrtl_delete(s, 0, 10);
+		fail_if(strcmp(s.str, "1234567"), "delete(\"1234567\", 0, 10)");
+		check_string(s);
+
+		fpcrtl_delete(s, 1, 1);
+		fail_if(strcmp(s.str, "234567"), "delete(\"1234567\", 1, 1)");
+		check_string(s);
+
+		fpcrtl_delete(s, 1, 100);
+		fail_if(strcmp(s.str, ""), "delete(\"234567\", 1, 100)");
+		check_string(s);
+
+		fpcrtl_delete(s2, 3, 2);
+		fail_if(strcmp(s2.str, "12567"), "delete(\"1234567\", 3, 2)");
+		check_string(s2);
+
+		fpcrtl_delete(s3, 3, 100);
+		fail_if(strcmp(s3.str, "12"), "delete(\"1234567\", 3, 100)");
+		check_string(s3);
+
+	}
+END_TEST
+
+START_TEST (test_FloatToStr)
+	{
+		double s = 1.2345;
+		string255 t = fpcrtl_floatToStr(s);
+		printf("-----Entering test floatToStr-----\n");
+		printf("FloatToStr(%f) = %s\n", s, t.str);
+		printf("-----Leaving test floatToStr-----\n");
+	}
+END_TEST
+
+START_TEST (test_random)
+	{
+		fpcrtl_randomize();
+		printf("-----Entering test random-----\n");
+		printf("random(5000) = %d\n", fpcrtl_random(5000));
+		printf("random(1) = %d\n", fpcrtl_random(1));
+		printf("random(2) = %d\n", fpcrtl_random(2));
+		printf("-----Leaving test random-----\n");
+
+	}
+END_TEST
+
+START_TEST (test_posS)
+	{
+		string255 substr1 = STRINIT("123");
+		string255 str1 = STRINIT("12345");
+
+		string255 substr2 = STRINIT("45");
+		string255 str2 = STRINIT("12345");
+
+		string255 substr3 = STRINIT("");
+		string255 str3 = STRINIT("12345");
+
+		string255 substr4 = STRINIT("123");
+		string255 str4 = STRINIT("");
+
+		string255 substr5 = STRINIT("123");
+		string255 str5 = STRINIT("456");
+
+		fail_unless(fpcrtl_posS(substr1, str1) == 1, "pos(123, 12345)");
+		fail_unless(fpcrtl_posS(substr2, str2) == 4, "pos(45, 12345)");
+		fail_unless(fpcrtl_posS(substr3, str3) == 0, "pos(, 12345)");
+		fail_unless(fpcrtl_posS(substr4, str4) == 0, "pos(123, )");
+		fail_unless(fpcrtl_posS(substr5, str5) == 0, "pos(123, 456)");
+	}
+END_TEST
+
+START_TEST (test_trunc)
+	{
+		  fail_unless(fpcrtl_trunc(123.456) == 123, "trunc(123.456)");
+		  fail_unless(fpcrtl_trunc(-123.456) == -123, "trunc(-123.456)");
+		  fail_unless(fpcrtl_trunc(12.3456) == 12, "trunc(12.3456)");
+		  fail_unless(fpcrtl_trunc(-12.3456) == -12, "trunc(-12.3456)");
+	}
+END_TEST
+
+START_TEST (test_odd)
+{
+	fail_unless(fpcrtl_odd(123) != 0, "odd(123)");
+	fail_unless(fpcrtl_odd(124) == 0, "odd(124)");
+	fail_unless(fpcrtl_odd(0) == 0, "odd(0)");
+	fail_unless(fpcrtl_odd(-1) != 0, "odd(-1)");
+	fail_unless(fpcrtl_odd(-2) == 0, "odd(-2)");
+}
+END_TEST
+
+START_TEST (test_sqr)
+{
+	fail_unless(fpcrtl_sqr(0) == 0, "sqr(0)");
+	fail_unless(fpcrtl_sqr(5) == 25, "sqr(5)");
+	fail_unless(fpcrtl_sqr(-5) == 25, "sqr(-5)");
+}
+END_TEST
+
+START_TEST (test_lowercase)
+{
+	string255 s1 = STRINIT("");
+	string255 s2 = STRINIT("a");
+	string255 s3 = STRINIT("abc");
+	string255 t;
+
+	t = fpcrtl_lowerCase(make_string(""));
+	fail_if(strcmp(t.str, s1.str), "lowerCase(\"\")");
+
+	t = fpcrtl_lowerCase(make_string("a"));
+	fail_if(strcmp(t.str, s2.str), "lowerCase(\"a\")");
+
+	t = fpcrtl_lowerCase(make_string("A"));
+	fail_if(strcmp(t.str, s2.str), "lowerCase(\"A\")");
+
+	t = fpcrtl_lowerCase(make_string("AbC"));
+	fail_if(strcmp(t.str, s3.str), "lowerCase(\"AbC\")");
+
+	t = fpcrtl_lowerCase(make_string("abc"));
+	fail_if(strcmp(t.str, s3.str), "lowerCase(\"abc\")");
+}
+END_TEST
+
+START_TEST (test_str)
+{
+	int8_t a1 = -8;
+	uint8_t a2 = 8;
+	int16_t a3 = -13;
+	uint16_t a4 = 13;
+	int32_t a5 = -19;
+	uint32_t a6 = 22;
+	int64_t a7 = -199999999999999;
+	uint64_t a8 = 200000000000000;
+
+	float a9 = 12345.6789;
+	double a10 = -9876.54321;
+
+	string255 s;
+
+	printf("-----Entering test str-----\n");
+
+	fpcrtl_str(a1, s);
+	printf("%d == %s\n", a1, s.str);
+
+	fpcrtl_str(a2, s);
+	printf("%u == %s\n", a2, s.str);
+
+	fpcrtl_str(a3, s);
+	printf("%d == %s\n", a3, s.str);
+
+	fpcrtl_str(a4, s);
+	printf("%u == %s\n", a4, s.str);
+
+	fpcrtl_str(a5, s);
+	printf("%d == %s\n", a5, s.str);
+
+	fpcrtl_str(a6, s);
+	printf("%u == %s\n", a6, s.str);
+
+	fpcrtl_str(a7, s);
+	printf("%lld == %s\n", a7, s.str);
+
+	fpcrtl_str(a8, s);
+	printf("%llu == %s\n", a8, s.str);
+
+	fpcrtl_str(a9, s);
+	printf("%f == %s\n", a9, s.str);
+
+	fpcrtl_str(a10, s);
+	printf("%f == %s\n", a10, s.str);
+
+	printf("-----Leaving test str------\n");
+}
+END_TEST
+
+Suite* system_suite(void)
+{
+	Suite *s = suite_create("system");
+
+	TCase *tc_core = tcase_create("Core");
+
+	tcase_add_test(tc_core, test_copy);
+	tcase_add_test(tc_core, test_FloatToStr);
+	tcase_add_test(tc_core, test_random);
+	tcase_add_test(tc_core, test_posS);
+	tcase_add_test(tc_core, test_trunc);
+	tcase_add_test(tc_core, test_delete);
+	tcase_add_test(tc_core, test_odd);
+	tcase_add_test(tc_core, test_sqr);
+	tcase_add_test(tc_core, test_lowercase);
+	tcase_add_test(tc_core, test_str);
+
+	suite_add_tcase(s, tc_core);
+
+	return s;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/tests/check_sysutils.c	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,80 @@
+#include <check.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "check_check.h"
+#include "../src/sysutils.h"
+
+static string255 make_string(const char* str)
+{
+	string255 s;
+	s.len = strlen(str);
+	memcpy(s.str, str, s.len + 1);
+	return s;
+}
+
+static int is_string_equal(string255 s1, string255 s2)
+{
+	return (s1.len == s2.len) && (strcmp(s1.str, s2.str) == 0);
+}
+
+START_TEST (test_trim)
+{
+	string255 t;
+
+	t = fpcrtl_trim(make_string(""));
+	fail_if(strcmp(t.str, ""), "trim(\"\")");
+
+	t = fpcrtl_trim(make_string("ab"));
+	fail_if(strcmp(t.str, "ab"), "trim(\"ab\")");
+
+	t = fpcrtl_trim(make_string(" "));
+	fail_if(strcmp(t.str, ""), "trim(\" \")");
+
+	t = fpcrtl_trim(make_string("   "));
+	fail_if(strcmp(t.str, ""), "trim(\"   \")");
+
+	t = fpcrtl_trim(make_string(" ab"));
+	fail_if(strcmp(t.str, "ab"), "trim(\" ab\")");
+
+	t = fpcrtl_trim(make_string("ab  "));
+	fail_if(strcmp(t.str, "ab"), "trim(\"ab  \")");
+
+	t = fpcrtl_trim(make_string("  ab  "));
+	fail_if(strcmp(t.str, "ab"), "trim(\"  ab  \")");
+
+}
+END_TEST
+
+START_TEST (test_strToInt)
+{
+	fail_unless(fpcrtl_strToInt(make_string("123")) == 123, "strToInt(\"123\")");
+	fail_unless(fpcrtl_strToInt(make_string("0")) == 0, "strToInt(\"0\")");
+	fail_unless(fpcrtl_strToInt(make_string("-123")) == -123, "strToInt(\"-123\")");
+}
+END_TEST
+
+START_TEST (test_extractFileName)
+{
+	fail_unless(is_string_equal(fpcrtl_extractFileName(make_string("abc")), make_string("abc")), "extractFileName(\"abc\")");
+	fail_unless(is_string_equal(fpcrtl_extractFileName(make_string("a:abc")), make_string("abc")), "extractFileName(\"a:abc\")");
+	fail_unless(is_string_equal(fpcrtl_extractFileName(make_string("/abc")), make_string("abc")), "extractFileName(\"/abc\")");
+	fail_unless(is_string_equal(fpcrtl_extractFileName(make_string("\\abc")), make_string("abc")), "extractFileName(\"\\abc\")");
+	fail_unless(is_string_equal(fpcrtl_extractFileName(make_string("/usr/bin/abc")), make_string("abc")), "extractFileName(\"/usr/bin/abc\")");
+	fail_unless(is_string_equal(fpcrtl_extractFileName(make_string("c:\\def\\abc")), make_string("abc")), "extractFileName(\"c:\\def\\abc\")");
+}
+END_TEST
+
+Suite* sysutils_suite(void)
+{
+	Suite *s = suite_create("sysutils");
+
+	TCase *tc_core = tcase_create("Core");
+
+	tcase_add_test(tc_core, test_trim);
+	tcase_add_test(tc_core, test_strToInt);
+	tcase_add_test(tc_core, test_extractFileName);
+
+	suite_add_tcase(s, tc_core);
+
+	return s;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/tests/fileio_test.c	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,59 @@
+
+#include "pas2c.h"
+
+#include "fpcrtl.h"
+
+char Pathz[1][128] = {"./"};
+int ptCurrTheme = 0;
+cThemeCFGFilename = "theme.cfg";
+const string255 __str79 = STRINIT("object");
+
+typedef struct __TResourceList {
+            Integer count;
+            string255 files[500 + 1];
+} TResourceList;
+
+TResourceList readThemeCfg_0()
+{
+    TResourceList readthemecfg_result;
+    string255 s;
+    string255 key;
+    TextFile f;
+    Integer i;
+    TResourceList result;
+    s = _strconcat(_strappend(Pathz[ptCurrTheme], '\x2f'), cThemeCFGFilename);
+
+    assign(f, s);
+    FileMode = 0;
+    reset(f);
+    result.count = 0;
+    while(!eof(f))
+    {
+        readLnS(f, s);
+        if((Length(s)) == (0))
+        {
+            continue;
+        }
+        if((s.s[1]) == ('\x3b'))
+        {
+            continue;
+        }
+        i = pos('\x3d', s);
+        key = trim(copy(s, 1, i - 1));
+        delete(s, 1, i);
+        if(_strcompare(key, __str79))
+        {
+            i = pos('\x2c', s);
+            result.files[result.count] = _strconcat(_strappend(Pathz[ptCurrTheme], '\x2f'), trim(copy(s, 1, i - 1)));
+            ++result.count;
+        }
+    }
+    close(f);
+    readthemecfg_result = result;
+    return readthemecfg_result;
+};
+
+int main(int argc, char** argv)
+{
+	readThemeCfg_0();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/hwc/rtl/tests/main.c	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,84 @@
+
+//#include <stdio.h>
+//#include "fpcrtl.h"
+//#include "fileio.h"
+//
+//string255 t = STRINIT("test");
+//string255 Pathz[1] = {STRINIT(".")};
+////int ptCurrTheme = 0;
+//string255 cThemeCFGFilename = STRINIT("theme.cfg");
+//const string255 __str79 = STRINIT("object");
+//string255 c1 = STRINIT("=");
+//string255 c2 = STRINIT("\x2c");
+//string255 c3 = STRINIT("\x2f");
+//
+//typedef struct __TResourceList {
+//            Integer count;
+//            string255 files[500 + 1];
+//} TResourceList;
+//
+//TResourceList readThemeCfg_0()
+//{
+//    TResourceList readthemecfg_result;
+//    string255 s;
+//    string255 key;
+//    TextFile f;
+//    Integer i;
+//    TResourceList result;
+//
+//    int t = 0;
+//
+//    s = _strconcat(_strappend(Pathz[ptCurrTheme], '\x2f'), cThemeCFGFilename);
+//
+//    assign(&f, s);
+//
+//    reset(&f);
+//
+//    if(f.fp == NULL){
+//    	readthemecfg_result.count = 0;
+//    	return readthemecfg_result;
+//    }
+//
+//    result.count = 0;
+//    while(!eof(&f))
+//    {
+//        readLnS(&f, &s);
+//
+//        if((Length(s)) == (0))
+//        {
+//            continue;
+//        }
+//        if((s.s[1]) == ('\x3b'))
+//        {
+//            continue;
+//        }
+//
+//        i = pos(c1, s);
+//
+//        key = fpcrtl_trim(fpcrtl_copy(s, 1, i - 1));
+//
+//        fpcrtl_delete(&s, 1, i);
+//
+//        if(_strcompare(key, __str79))
+//        {
+//            i = pos(c2, s);
+//            result.files[result.count] = _strconcat(_strappend(Pathz[ptCurrTheme], '\x2f'), trim(copy(s, 1, i - 1)));
+//            ++result.count;
+//        }
+//    }
+//
+//    close(&f);
+//    readthemecfg_result = result;
+//    return readthemecfg_result;
+//}
+//
+int main(int argc, char** argv)
+{
+	int i;
+
+//	TResourceList result = readThemeCfg_0();
+//	for(i = 0; i < result.count; i++){
+//		printf("%s\n", result.files[i].str);
+//	}
+
+}
--- a/share/hedgewars/Data/CMakeLists.txt	Sun Jun 09 12:20:19 2013 +0200
+++ b/share/hedgewars/Data/CMakeLists.txt	Sun Jun 09 12:22:53 2013 +0200
@@ -1,3 +1,7 @@
 foreach(dir "Fonts" "Forts" "Graphics" "Locale" "Maps" "Music" "Sounds" "Themes" "Missions" "Names" "misc" "Scripts")
-  add_subdirectory(${dir})
+    add_subdirectory(${dir})
 endforeach(dir)
+
+if(${GL2})
+    add_subdirectory(Shaders)
+endif(${GL2})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Shaders/CMakeLists.txt	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,7 @@
+file(GLOB vertshaders *.vs)
+file(GLOB fragshaders *.fs)
+
+install(FILES
+	${vertshaders}
+	${fragshaders}
+	DESTINATION ${SHAREPATH}Data/Shaders)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Shaders/default.fs	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,15 @@
+uniform sampler2D tex0;
+uniform vec4 tint;
+uniform bool enableTexture;
+
+varying vec2 tex;
+
+
+void main()
+{
+    if(enableTexture){
+        gl_FragColor = texture2D(tex0, tex) * tint;
+    }else{
+        gl_FragColor = tint;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Shaders/default.vs	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,16 @@
+
+
+attribute vec2 vertex;
+attribute vec2 texcoord;
+attribute vec4 colors;
+
+varying vec2 tex;
+
+uniform mat4 mvp;
+
+void main()
+{
+    vec4 p = mvp * vec4(vertex, 0.0, 1.0);
+    gl_Position = p;
+    tex = texcoord;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Shaders/water.fs	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,8 @@
+
+varying vec4 vcolor;
+
+
+void main()
+{
+    gl_FragColor = vcolor;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Shaders/water.vs	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,15 @@
+
+
+attribute vec2 vertex;
+attribute vec4 color;
+
+varying vec4 vcolor;
+
+uniform mat4 mvp;
+
+void main()
+{
+    vec4 p = mvp * vec4(vertex, 0.0, 1.0);
+    gl_Position = p;
+    vcolor = color;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/pas2c/CMakeLists.txt	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,29 @@
+set(pas2c_sources
+        Main.hs
+        PascalBasics.hs
+        PascalParser.hs
+        PascalPreprocessor.hs
+        PascalUnitSyntaxTree.hs
+        Pas2C.hs
+    )
+
+set(pas2c_main ${CMAKE_SOURCE_DIR}/tools/pas2c/Main.hs)
+
+set(ghc_flags
+        --make ${pas2c_main}
+        -i${CMAKE_SOURCE_DIR}/tools/pas2c/
+        -o ${EXECUTABLE_OUTPUT_PATH}/pas2c${CMAKE_EXECUTABLE_SUFFIX}
+        -odir ${CMAKE_CURRENT_BINARY_DIR}
+        -hidir ${CMAKE_CURRENT_BINARY_DIR}
+        ${haskell_flags}
+    )
+
+add_custom_command(OUTPUT "${EXECUTABLE_OUTPUT_PATH}/pas2c${CMAKE_EXECUTABLE_SUFFIX}"
+        COMMAND "${ghc_executable}"
+        ARGS ${ghc_flags}
+        MAIN_DEPENDENCY ${hwserv_main}
+        DEPENDS ${hwserver_sources}
+        )
+
+add_custom_target(pas2c ALL DEPENDS "${EXECUTABLE_OUTPUT_PATH}/pas2c${CMAKE_EXECUTABLE_SUFFIX}")
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/pas2c/Main.hs	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,71 @@
+module Main( main ) where
+
+import System.Console.GetOpt
+import System.Environment
+import System.Exit
+import System.IO
+import Data.Maybe( fromMaybe, isJust, fromJust )
+import Data.List (find)
+import Control.Monad
+import Pas2C
+
+main = do
+    args <- getArgs
+    if length args == 0
+    then do
+        name <- getProgName
+        hPutStrLn stderr $ usageInfo header options
+        exitFailure
+    else do
+        case getOpt RequireOrder options args of
+          (flags, [],      []) | enoughFlags flags -> do
+                let m = flag flags isName
+                let i = flag flags isInput
+                let o = flag flags isOutput
+                let a = fromMaybe o $ liftM extractString $ find isAlt flags
+                hPutStrLn stdout $ "--------Pas2C Config--------"
+                hPutStrLn stdout $ "Main module: " ++ m
+                hPutStrLn stdout $ "Input path : " ++ i
+                hPutStrLn stdout $ "Output path: " ++ o
+                hPutStrLn stdout $ "Altern path: " ++ a
+                hPutStrLn stdout $ "----------------------------"
+                pas2C m (i++"/") (o++"/") (a++"/")
+                hPutStrLn stdout $ "----------------------------"
+                      | otherwise ->  error $ usageInfo header options
+          (_,     nonOpts, [])     -> error $ "unrecognized arguments: " ++ unwords nonOpts
+          (_,     _,       msgs)   -> error $ usageInfo header options
+    where 
+        header = "Freepascal to C conversion! Please specify -n -i -o options.\n"
+        enoughFlags f = and $ map (isJust . flip find f) [isName, isInput, isOutput]
+        flag f = extractString . fromJust . flip find f
+
+
+data Flag = HelpMessage | Name String | Input String | Output String | Alternate String
+
+
+extractString :: Flag -> String
+extractString (Name s) = s
+extractString (Input s) = s
+extractString (Output s) = s
+extractString (Alternate s) = s
+extractString _ = undefined
+
+isName, isInput, isOutput, isAlt :: Flag -> Bool
+isName (Name _) = True
+isName _ = False
+isInput (Input _) = True
+isInput _ = False
+isOutput (Output _) = True
+isOutput _ = False
+isAlt (Alternate _) = True
+isAlt _ = False
+
+options :: [OptDescr Flag]
+options = [
+    Option ['h'] ["help"]      (NoArg HelpMessage)      "print this help message",
+    Option ['n'] ["name"]      (ReqArg Name "MAIN")     "name of the main Pascal module",
+    Option ['i'] ["input"]     (ReqArg Input "DIR")     "input directory, where .pas files will be read",
+    Option ['o'] ["output"]    (ReqArg Output "DIR")    "output directory, where .c/.h files will be written",
+    Option ['a'] ["alternate"] (ReqArg Alternate "DIR") "alternate input directory, for out of source builds"
+  ]
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/pas2c/Pas2C.hs	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,1172 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+module Pas2C where
+
+import Text.PrettyPrint.HughesPJ
+import Data.Maybe
+import Data.Char
+import Text.Parsec.Prim hiding (State)
+import Control.Monad.State
+import System.IO
+import System.Directory
+import Control.Monad.IO.Class
+import PascalPreprocessor
+import Control.Exception
+import System.IO.Error
+import qualified Data.Map as Map
+import qualified Data.Set as Set
+import Data.List (find)
+import Numeric
+
+import PascalParser(pascalUnit)
+import PascalUnitSyntaxTree
+
+
+data InsertOption =
+    IOInsert
+    | IOInsertWithType Doc
+    | IOLookup
+    | IOLookupLast
+    | IOLookupFunction Int
+    | IODeferred
+
+data Record = Record
+    {
+        lcaseId :: String,
+        baseType :: BaseType,
+        typeDecl :: Doc
+    }
+    deriving Show
+type Records = Map.Map String [Record]
+data RenderState = RenderState
+    {
+        currentScope :: Records,
+        lastIdentifier :: String,
+        lastType :: BaseType,
+        isFunctionType :: Bool, -- set to true if the current function parameter is functiontype
+        lastIdTypeDecl :: Doc,
+        stringConsts :: [(String, String)],
+        uniqCounter :: Int,
+        toMangle :: Set.Set String,
+        enums :: [(String, [String])], -- store all declared enums
+        currentUnit :: String,
+        currentFunctionResult :: String,
+        namespaces :: Map.Map String Records
+    }
+
+rec2Records = map (\(a, b) -> Record a b empty)
+
+emptyState = RenderState Map.empty "" BTUnknown False empty [] 0 Set.empty [] "" ""
+
+getUniq :: State RenderState Int
+getUniq = do
+    i <- gets uniqCounter
+    modify(\s -> s{uniqCounter = uniqCounter s + 1})
+    return i
+
+addStringConst :: String -> State RenderState Doc
+addStringConst str = do
+    strs <- gets stringConsts
+    let a = find ((==) str . snd) strs
+    if isJust a then
+        do
+        modify (\s -> s{lastType = BTString})
+        return . text . fst . fromJust $ a
+    else
+        do
+        i <- getUniq
+        let sn = "__str" ++ show i
+        modify (\s -> s{lastType = BTString, stringConsts = (sn, str) : strs})
+        return $ text sn
+
+escapeStr :: String -> String
+escapeStr = foldr escapeChar []
+
+escapeChar :: Char -> ShowS
+escapeChar '"' s = "\\\"" ++ s
+escapeChar '\\' s = "\\\\" ++ s
+escapeChar a s = a : s
+
+strInit :: String -> Doc
+strInit a = text "STRINIT" <> parens (doubleQuotes (text $ escapeStr a))
+
+renderStringConsts :: State RenderState Doc
+renderStringConsts = liftM (vcat . map (\(a, b) -> text "static const string255" <+> (text a) <+> text "=" <+> strInit b <> semi))
+    $ gets stringConsts
+
+docToLower :: Doc -> Doc
+docToLower = text . map toLower . render
+
+pas2C :: String -> String -> String -> String -> IO ()
+pas2C fn inputPath outputPath alternateInputPath = do
+    s <- flip execStateT initState $ f fn
+    renderCFiles s outputPath
+    where
+    printLn = liftIO . hPutStrLn stdout
+    print = liftIO . hPutStr stdout
+    initState = Map.empty
+    f :: String -> StateT (Map.Map String PascalUnit) IO ()
+    f fileName = do
+        processed <- gets $ Map.member fileName
+        unless processed $ do
+            print ("Preprocessing '" ++ fileName ++ ".pas'... ")
+            fc' <- liftIO
+                $ tryJust (guard . isDoesNotExistError)
+                $ preprocess inputPath alternateInputPath (fileName ++ ".pas")
+            case fc' of
+                (Left a) -> do
+                    modify (Map.insert fileName (System []))
+                    printLn "doesn't exist"
+                (Right fc) -> do
+                    print "ok, parsing... "
+                    let ptree = parse pascalUnit fileName fc
+                    case ptree of
+                         (Left a) -> do
+                            liftIO $ writeFile (outputPath ++ "preprocess.out") fc
+                            printLn $ show a ++ "\nsee preprocess.out for preprocessed source"
+                            fail "stop"
+                         (Right a) -> do
+                            printLn "ok"
+                            modify (Map.insert fileName a)
+                            mapM_ f (usesFiles a)
+
+
+renderCFiles :: Map.Map String PascalUnit -> String -> IO ()
+renderCFiles units outputPath = do
+    let u = Map.toList units
+    let nss = Map.map (toNamespace nss) units
+    --hPutStrLn stderr $ "Units: " ++ (show . Map.keys . Map.filter (not . Map.null) $ nss)
+    --writeFile "pas2c.log" $ unlines . map (\t -> show (fst t) ++ "\n" ++ (unlines . map ((:) '\t' . show) . snd $ t)) . Map.toList $ nss
+    mapM_ (toCFiles outputPath nss) u
+    where
+    toNamespace :: Map.Map String Records -> PascalUnit -> Records
+    toNamespace nss (System tvs) =
+        currentScope $ execState f (emptyState nss)
+        where
+        f = do
+            checkDuplicateFunDecls tvs
+            mapM_ (tvar2C True False True False) tvs
+    toNamespace nss (Redo tvs) = -- functions that are re-implemented, add prefix to all of them
+        currentScope $ execState f (emptyState nss){currentUnit = "fpcrtl_"}
+        where
+        f = do
+            checkDuplicateFunDecls tvs
+            mapM_ (tvar2C True False True False) tvs
+    toNamespace _ (Program {}) = Map.empty
+    toNamespace nss (Unit (Identifier i _) interface _ _ _) =
+        currentScope $ execState (interface2C interface True) (emptyState nss){currentUnit = map toLower i ++ "_"}
+
+withState' :: (RenderState -> RenderState) -> State RenderState a -> State RenderState a
+withState' f sf = do
+    st <- liftM f get
+    let (a, s) = runState sf st
+    modify(\st -> st{
+        lastType = lastType s
+        , uniqCounter = uniqCounter s
+        , stringConsts = stringConsts s
+        })
+    return a
+
+withLastIdNamespace f = do
+    li <- gets lastIdentifier
+    nss <- gets namespaces
+    withState' (\st -> st{currentScope = fromMaybe Map.empty $ Map.lookup li (namespaces st)}) f
+
+withRecordNamespace :: String -> [Record] -> State RenderState Doc -> State RenderState Doc
+withRecordNamespace _ [] = error "withRecordNamespace: empty record"
+withRecordNamespace prefix recs = withState' f
+    where
+        f st = st{currentScope = Map.unionWith un records (currentScope st), currentUnit = ""}
+        records = Map.fromList $ map (\(Record a b d) -> (map toLower a, [Record (prefix ++ a) b d])) recs
+        un [a] b = a : b
+
+toCFiles :: String -> Map.Map String Records -> (String, PascalUnit) -> IO ()
+toCFiles _ _ (_, System _) = return ()
+toCFiles _ _ (_, Redo _) = return ()
+toCFiles outputPath ns p@(fn, pu) = do
+    hPutStrLn stdout $ "Rendering '" ++ fn ++ "'..."
+    toCFiles' p
+    where
+    toCFiles' (fn, p@(Program {})) = writeFile (outputPath ++ fn ++ ".c") $ "#include \"fpcrtl.h\"\n" ++ (render2C initialState . pascal2C) p
+    toCFiles' (fn, (Unit unitId@(Identifier i _) interface implementation _ _)) = do
+        let (a, s) = runState (id2C IOInsert (setBaseType BTUnit unitId) >> interface2C interface True) initialState{currentUnit = map toLower i ++ "_"}
+            (a', s') = runState (id2C IOInsert (setBaseType BTUnit unitId) >> interface2C interface False) initialState{currentUnit = map toLower i ++ "_"}
+            enumDecl = (renderEnum2Strs (enums s) False)
+            enumImpl = (renderEnum2Strs (enums s) True)
+        writeFile (outputPath ++ fn ++ ".h") $ "#pragma once\n\n#include \"pas2c.h\"\n\n" ++ (render (a $+$ text "")) ++ "\n" ++ enumDecl
+        writeFile (outputPath ++ fn ++ ".c") $ "#include \"fpcrtl.h\"\n\n#include \"" ++ fn ++ ".h\"\n" ++ render (a' $+$ text "") ++ (render2C s . implementation2C) implementation ++ "\n" ++ enumImpl
+    initialState = emptyState ns
+
+    render2C :: RenderState -> State RenderState Doc -> String
+    render2C st p =
+        let (a, s) = runState p st in
+        render a
+
+renderEnum2Strs :: [(String, [String])] -> Bool -> String
+renderEnum2Strs enums implement =
+    render $ foldl ($+$) empty $ map (\en -> let d = decl (fst en) in if implement then d $+$ enum2strBlock (snd en) else d <> semi) enums
+    where
+    decl id = text "string255 __attribute__((overloadable)) fpcrtl_GetEnumName" <> parens (text "int dummy, const" <+> text id <+> text "enumvar") 
+    enum2strBlock en = 
+            text "{"
+            $+$
+            (nest 4 $
+                text "switch(enumvar){"
+                $+$
+                (foldl ($+$) empty $ map (\e -> text "case" <+> text e <> colon $+$ (nest 4 $ text "return fpcrtl_make_string" <> (parens $ doubleQuotes $ text e) <> semi $+$ text "break;")) en)
+                $+$
+                text "default: assert(0);"
+                $+$
+                (nest 4 $ text "return fpcrtl_make_string(\"nonsense\");")
+                $+$
+                text "}"
+            )
+            $+$
+            text "}"
+
+usesFiles :: PascalUnit -> [String]
+usesFiles (Program _ (Implementation uses _) _) = ["pas2cSystem", "pas2cRedo"] ++ uses2List uses
+usesFiles (Unit _ (Interface uses1 _) (Implementation uses2 _) _ _) = ["pas2cSystem", "pas2cRedo"] ++ uses2List uses1 ++ uses2List uses2
+usesFiles (System {}) = []
+usesFiles (Redo {}) = []
+
+pascal2C :: PascalUnit -> State RenderState Doc
+pascal2C (Unit _ interface implementation init fin) =
+    liftM2 ($+$) (interface2C interface True) (implementation2C implementation)
+
+pascal2C (Program _ implementation mainFunction) = do
+    impl <- implementation2C implementation
+    [main] <- tvar2C True False True True (FunctionDeclaration (Identifier "main" (BTInt True)) False False (SimpleType $ Identifier "int" (BTInt True)) [VarDeclaration False False ([Identifier "argc" (BTInt True)], SimpleType (Identifier "Integer" (BTInt True))) Nothing, VarDeclaration False False ([Identifier "argv" BTUnknown], SimpleType (Identifier "PPChar" BTUnknown)) Nothing] (Just (TypesAndVars [], mainFunction)))
+
+    return $ impl $+$ main
+
+
+-- the second bool indicates whether do normal interface translation or generate variable declarations
+-- that will be inserted into implementation files
+interface2C :: Interface -> Bool -> State RenderState Doc
+interface2C (Interface uses tvars) True = do
+    u <- uses2C uses
+    tv <- typesAndVars2C True True True tvars
+    r <- renderStringConsts
+    return (u $+$ r $+$ tv)
+interface2C (Interface uses tvars) False = do
+    u <- uses2C uses
+    tv <- typesAndVars2C True False False tvars
+    r <- renderStringConsts
+    return tv
+
+implementation2C :: Implementation -> State RenderState Doc
+implementation2C (Implementation uses tvars) = do
+    u <- uses2C uses
+    tv <- typesAndVars2C True False True tvars
+    r <- renderStringConsts
+    return (u $+$ r $+$ tv)
+
+checkDuplicateFunDecls :: [TypeVarDeclaration] -> State RenderState ()
+checkDuplicateFunDecls tvs =
+    modify $ \s -> s{toMangle = Map.keysSet . Map.filter (> 1) . foldr ins initMap $ tvs}
+    where
+        initMap = Map.empty
+        --initMap = Map.fromList [("reset", 2)]
+        ins (FunctionDeclaration (Identifier i _) _ _ _ _ _) m = Map.insertWith (+) (map toLower i) 1 m
+        ins _ m = m
+
+-- the second bool indicates whether declare variable as extern or not
+-- the third bool indicates whether include types or not
+
+typesAndVars2C :: Bool -> Bool -> Bool -> TypesAndVars -> State RenderState Doc
+typesAndVars2C b externVar includeType(TypesAndVars ts) = do
+    checkDuplicateFunDecls ts
+    liftM (vcat . map (<> semi) . concat) $ mapM (tvar2C b externVar includeType False) ts
+
+setBaseType :: BaseType -> Identifier -> Identifier
+setBaseType bt (Identifier i _) = Identifier i bt
+
+uses2C :: Uses -> State RenderState Doc
+uses2C uses@(Uses unitIds) = do
+
+    mapM_ injectNamespace (Identifier "pas2cSystem" undefined : unitIds)
+    mapM_ injectNamespace (Identifier "pas2cRedo" undefined : unitIds)
+    mapM_ (id2C IOInsert . setBaseType BTUnit) unitIds
+    return $ vcat . map (\i -> text $ "#include \"" ++ i ++ ".h\"") $ uses2List uses
+    where
+    injectNamespace (Identifier i _) = do
+        getNS <- gets (flip Map.lookup . namespaces)
+        modify (\s -> s{currentScope = Map.unionWith (++) (fromMaybe Map.empty (getNS i)) $ currentScope s})
+
+uses2List :: Uses -> [String]
+uses2List (Uses ids) = map (\(Identifier i _) -> i) ids
+
+
+setLastIdValues vv = (\s -> s{lastType = baseType vv, lastIdentifier = lcaseId vv, lastIdTypeDecl = typeDecl vv})
+
+id2C :: InsertOption -> Identifier -> State RenderState Doc
+id2C IOInsert i = id2C (IOInsertWithType empty) i
+id2C (IOInsertWithType d) (Identifier i t) = do
+    ns <- gets currentScope
+    tom <- gets (Set.member n . toMangle)
+    cu <- gets currentUnit
+    let (i', t') = case (t, tom) of
+            (BTFunction _ p _, True) -> (cu ++ i ++ ('_' : show (length p)), t)
+            (BTFunction _ _ _, _) -> (cu ++ i, t)
+            (BTVarParam t', _) -> ('(' : '*' : i ++ ")" , t')
+            _ -> (i, t)
+    modify (\s -> s{currentScope = Map.insertWith (++) n [Record i' t' d] (currentScope s), lastIdentifier = n})
+    return $ text i'
+    where
+        n = map toLower i
+
+id2C IOLookup i = id2CLookup head i
+id2C IOLookupLast i = id2CLookup last i
+id2C (IOLookupFunction params) (Identifier i t) = do
+    let i' = map toLower i
+    v <- gets $ Map.lookup i' . currentScope
+    lt <- gets lastType
+    if isNothing v then
+        error $ "Not defined: '" ++ i' ++ "'\n" ++ show lt ++ "\nwith num of params = " ++ show params ++ "\n" ++ show v
+        else
+        let vv = fromMaybe (head $ fromJust v) . find checkParam $ fromJust v in
+            modify (setLastIdValues vv) >> (return . text . lcaseId $ vv)
+    where
+        checkParam (Record _ (BTFunction _ p _) _) = (length p) == params
+        checkParam _ = False
+id2C IODeferred (Identifier i t) = do
+    let i' = map toLower i
+    v <- gets $ Map.lookup i' . currentScope
+    if (isNothing v) then
+        modify (\s -> s{lastType = BTUnknown, lastIdentifier = i}) >> return (text i)
+        else
+        let vv = head $ fromJust v in modify (setLastIdValues vv) >> (return . text . lcaseId $ vv)
+
+id2CLookup :: ([Record] -> Record) -> Identifier -> State RenderState Doc
+id2CLookup f (Identifier i t) = do
+    let i' = map toLower i
+    v <- gets $ Map.lookup i' . currentScope
+    lt <- gets lastType
+    if isNothing v then
+        error $ "Not defined: '" ++ i' ++ "'\n" ++ show lt
+        else
+        let vv = f $ fromJust v in modify (setLastIdValues vv) >> (return . text . lcaseId $ vv)
+
+
+
+id2CTyped :: TypeDecl -> Identifier -> State RenderState Doc
+id2CTyped = id2CTyped2 Nothing
+
+id2CTyped2 :: Maybe Doc -> TypeDecl -> Identifier -> State RenderState Doc
+id2CTyped2 md t (Identifier i _) = do
+    tb <- resolveType t
+    case (t, tb) of
+        (_, BTUnknown) -> do
+            error $ "id2CTyped: type BTUnknown for " ++ show i ++ "\ntype: " ++ show t
+        (SimpleType {}, BTRecord _ r) -> do
+            ts <- type2C t
+            id2C (IOInsertWithType $ ts empty) (Identifier i (BTRecord (render $ ts empty) r))
+        (_, BTRecord _ r) -> do
+            ts <- type2C t
+            id2C (IOInsertWithType $ ts empty) (Identifier i (BTRecord i r))
+        _ -> case md of
+                Nothing -> id2C IOInsert (Identifier i tb)
+                Just ts -> id2C (IOInsertWithType ts) (Identifier i tb)
+
+typeVarDecl2BaseType :: [TypeVarDeclaration] -> State RenderState [(Bool, BaseType)]
+typeVarDecl2BaseType d = do
+    st <- get
+    result <- sequence $ concat $ map resolveType' d
+    put st -- restore state (not sure if necessary)
+    return result
+    where
+        resolveType' :: TypeVarDeclaration -> [State RenderState (Bool, BaseType)]
+        resolveType' (VarDeclaration isVar _ (ids, t) _) = replicate (length ids) (resolveTypeHelper' (resolveType t) isVar)
+        resolveType' _ = error "typeVarDecl2BaseType: not a VarDeclaration"
+        resolveTypeHelper' :: State RenderState BaseType -> Bool -> State RenderState (Bool, BaseType)
+        resolveTypeHelper' st b = do
+            bt <- st
+            return (b, bt)
+	
+resolveType :: TypeDecl -> State RenderState BaseType
+resolveType st@(SimpleType (Identifier i _)) = do
+    let i' = map toLower i
+    v <- gets $ Map.lookup i' . currentScope
+    if isJust v then return . baseType . head $ fromJust v else return $ f i'
+    where
+    f "uinteger" = BTInt False
+    f "integer" = BTInt True
+    f "pointer" = BTPointerTo BTVoid
+    f "boolean" = BTBool
+    f "float" = BTFloat
+    f "char" = BTChar
+    f "string" = BTString
+    f _ = error $ "Unknown system type: " ++ show st
+resolveType (PointerTo (SimpleType (Identifier i _))) = return . BTPointerTo $ BTUnresolved (map toLower i)
+resolveType (PointerTo t) = liftM BTPointerTo $ resolveType t
+resolveType (RecordType tv mtvs) = do
+    tvs <- mapM f (concat $ tv : fromMaybe [] mtvs)
+    return . BTRecord "" . concat $ tvs
+    where
+        f :: TypeVarDeclaration -> State RenderState [(String, BaseType)]
+        f (VarDeclaration _ _ (ids, td) _) = mapM (\(Identifier i _) -> liftM ((,) i) $ resolveType td) ids
+resolveType (ArrayDecl (Just i) t) = do
+    t' <- resolveType t
+    return $ BTArray i (BTInt True) t'
+resolveType (ArrayDecl Nothing t) = liftM (BTArray RangeInfinite (BTInt True)) $ resolveType t
+resolveType (FunctionType t a) = do
+	bts <- typeVarDecl2BaseType a
+	liftM (BTFunction False bts) $ resolveType t
+resolveType (DeriveType (InitHexNumber _)) = return (BTInt True)
+resolveType (DeriveType (InitNumber _)) = return (BTInt True)
+resolveType (DeriveType (InitFloat _)) = return BTFloat
+resolveType (DeriveType (InitString _)) = return BTString
+resolveType (DeriveType (InitBinOp {})) = return (BTInt True)
+resolveType (DeriveType (InitPrefixOp _ e)) = initExpr2C e >> gets lastType
+resolveType (DeriveType (BuiltInFunction{})) = return (BTInt True)
+resolveType (DeriveType (InitReference (Identifier{}))) = return BTBool -- TODO: derive from actual type
+resolveType (DeriveType _) = return BTUnknown
+resolveType (String _) = return BTString
+resolveType VoidType = return BTVoid
+resolveType (Sequence ids) = return $ BTEnum $ map (\(Identifier i _) -> map toLower i) ids
+resolveType (RangeType _) = return $ BTVoid
+resolveType (Set t) = liftM BTSet $ resolveType t
+resolveType (VarParamType t) = liftM BTVarParam $ resolveType t
+
+
+resolve :: String -> BaseType -> State RenderState BaseType
+resolve s (BTUnresolved t) = do
+    v <- gets $ Map.lookup t . currentScope
+    if isJust v then
+        resolve s . baseType . head . fromJust $ v
+        else
+        error $ "Unknown type " ++ show t ++ "\n" ++ s
+resolve _ t = return t
+
+fromPointer :: String -> BaseType -> State RenderState BaseType
+fromPointer s (BTPointerTo t) = resolve s t
+fromPointer s t = do
+    error $ "Dereferencing from non-pointer type " ++ show t ++ "\n" ++ s
+
+
+functionParams2C params = liftM (hcat . punctuate comma . concat) $ mapM (tvar2C False False True True) params
+
+numberOfDeclarations :: [TypeVarDeclaration] -> Int
+numberOfDeclarations = sum . map cnt
+    where
+        cnt (VarDeclaration _ _ (ids, _) _) = length ids
+        cnt _ = 1
+
+hasPassByReference :: [TypeVarDeclaration] -> Bool
+hasPassByReference = or . map isVar
+    where
+        isVar (VarDeclaration v _ (_, _) _) = v
+        isVar _ = error $ "hasPassByReference called not on function parameters"
+
+toIsVarList :: [TypeVarDeclaration] -> [Bool]
+toIsVarList = concatMap isVar
+    where
+        isVar (VarDeclaration v _ (p, _) _) = replicate (length p) v
+        isVar _ = error $ "toIsVarList called not on function parameters"
+
+
+funWithVarsToDefine :: String -> [TypeVarDeclaration] -> Doc
+funWithVarsToDefine n params = text "#define" <+> text n <> parens abc <+> text (n ++ "__vars") <> parens cparams
+    where
+        abc = hcat . punctuate comma . map (char . fst) $ ps
+        cparams = hcat . punctuate comma . map (\(c, v) -> if v then char '&' <> parens (char c) else char c) $ ps
+        ps = zip ['a'..] (toIsVarList params)
+
+fun2C :: Bool -> String -> TypeVarDeclaration -> State RenderState [Doc]
+fun2C _ _ (FunctionDeclaration name inline overload returnType params Nothing) = do
+    t <- type2C returnType
+    t'<- gets lastType
+    bts <- typeVarDecl2BaseType params
+    p <- withState' id $ functionParams2C params
+    n <- liftM render . id2C IOInsert $ setBaseType (BTFunction False bts t') name
+    let decor = if overload then text "__attribute__((overloadable))" else empty
+    return [t empty <+> decor <+> text n <> parens p]
+
+fun2C True rv (FunctionDeclaration name@(Identifier i bt) inline overload returnType params (Just (tvars, phrase))) = do
+    let isVoid = case returnType of
+            VoidType -> True
+            _ -> False
+
+    let res = docToLower $ text rv <> if isVoid then empty else text "_result"
+    t <- type2C returnType
+    t' <- gets lastType
+
+    bts <- typeVarDecl2BaseType params
+    cu <- gets currentUnit
+    notDeclared <- liftM isNothing . gets $ Map.lookup (map toLower i) . currentScope
+
+    n <- liftM render . id2C IOInsert $ setBaseType (BTFunction hasVars bts t') name
+    let resultId = if isVoid
+                    then n -- void type doesn't have result, solving recursive procedure calls
+                    else (render res)
+
+    (p, ph) <- withState' (\st -> st{currentScope = Map.insertWith un (map toLower rv) [Record resultId (if isVoid then (BTFunction hasVars bts t') else t') empty] $ currentScope st
+            , currentFunctionResult = if isVoid then [] else render res}) $ do
+        p <- functionParams2C params
+        ph <- liftM2 ($+$) (typesAndVars2C False False True tvars) (phrase2C' phrase)
+        return (p, ph)
+
+    let phrasesBlock = if isVoid then ph else t empty <+> res <> semi $+$ ph $+$ text "return" <+> res <> semi
+    let define = if hasVars then text "#ifndef" <+> text n $+$ funWithVarsToDefine n params $+$ text "#endif" else empty
+    let inlineDecor = if inline then case notDeclared of
+                                    True -> text "static inline"
+                                    False -> text "inline"
+                          else empty
+        overloadDecor = if overload then text "__attribute__((overloadable))" else empty
+    return [
+        --define
+        -- $+$
+        --(if notDeclared && hasVars then funWithVarsToDefine n params else empty) $+$
+        inlineDecor <+> t empty <+> overloadDecor <+> text n <> parens p
+        $+$
+        text "{"
+        $+$
+        nest 4 phrasesBlock
+        $+$
+        text "}"]
+    where
+    phrase2C' (Phrases p) = liftM vcat $ mapM phrase2C p
+    phrase2C' p = phrase2C p
+    un [a] b = a : b
+    hasVars = hasPassByReference params
+
+fun2C False _ (FunctionDeclaration (Identifier name _) _ _ _ _ _) = error $ "nested functions not allowed: " ++ name
+fun2C _ tv _ = error $ "fun2C: I don't render " ++ show tv
+
+-- the second bool indicates whether declare variable as extern or not
+-- the third bool indicates whether include types or not
+-- the fourth bool indicates whether ignore initialization or not (basically for dynamic arrays since we cannot do initialization in function params)
+tvar2C :: Bool -> Bool -> Bool -> Bool -> TypeVarDeclaration -> State RenderState [Doc]
+tvar2C b _ includeType _ f@(FunctionDeclaration (Identifier name _) _ _ _ _ _) = do
+    t <- fun2C b name f
+    if includeType then return t else return []
+tvar2C _ _ includeType _ td@(TypeDeclaration i' t) = do
+    i <- id2CTyped t i'
+    tp <- type2C t
+    let res = if includeType then [text "typedef" <+> tp i] else []
+    case t of
+        (Sequence ids) -> do
+            modify(\s -> s{enums = (render i, map (\(Identifier i _) -> i) ids) : enums s})
+            return res
+        _ -> return res
+
+tvar2C _ _ _ _ (VarDeclaration True _ (ids, t) Nothing) = do
+    t' <- liftM ((empty <+>) . ) $ type2C t
+    liftM (map(\i -> t' i)) $ mapM (id2CTyped2 (Just $ t' empty) (VarParamType t)) ids
+
+tvar2C _ externVar includeType ignoreInit (VarDeclaration _ isConst (ids, t) mInitExpr) = do
+    t' <- liftM (((if isConst then text "static const" else if externVar
+                                                                then text "extern"
+                                                                else empty)
+                   <+>) . ) $ type2C t
+    ie <- initExpr mInitExpr
+    lt <- gets lastType
+    case (isConst, lt, ids, mInitExpr) of
+         (True, BTInt _, [i], Just _) -> do
+             i' <- id2CTyped t i
+             return $ if includeType then [text "enum" <> braces (i' <+> ie)] else []
+         (True, BTFloat, [i], Just e) -> do
+             i' <- id2CTyped t i
+             ie <- initExpr2C e
+             return $ if includeType then [text "#define" <+> i' <+> parens ie <> text "\n"] else []
+         (_, BTFunction{}, _, Nothing) -> liftM (map(\i -> t' i)) $ mapM (id2CTyped t) ids
+         (_, BTArray r _ _, [i], _) -> do
+            i' <- id2CTyped t i
+            ie' <- return $ case (r, mInitExpr, ignoreInit) of
+                (RangeInfinite, Nothing, False) -> text "= NULL" -- force dynamic array to be initialized as NULL if not initialized at all
+                (_, _, _) -> ie
+            result <- liftM (map(\i -> varDeclDecision isConst includeType (t' i) ie')) $ mapM (id2CTyped t) ids
+            case (r, ignoreInit) of
+                (RangeInfinite, False) ->
+                    -- if the array is dynamic, add dimension info to it
+                    return $ [dimDecl] ++ result
+                    where
+                        arrayDimStr = show $ arrayDimension t
+                        arrayDimInitExp = text ("={" ++ ".dim = " ++ arrayDimStr ++ ", .a = {0, 0, 0, 0}}")
+                        dimDecl = varDeclDecision isConst includeType (text "fpcrtl_dimension_t" <+>  i' <> text "_dimension_info") arrayDimInitExp
+
+                (_, _) -> return result
+
+         _ -> liftM (map(\i -> varDeclDecision isConst includeType (t' i) ie)) $ mapM (id2CTyped2 (Just $ t' empty) t) ids
+    where
+    initExpr Nothing = return $ empty
+    initExpr (Just e) = liftM (text "=" <+>) (initExpr2C e)
+    varDeclDecision True True varStr expStr = varStr <+> expStr
+    varDeclDecision False True varStr expStr = if externVar then varStr else varStr <+> expStr
+    varDeclDecision False False varStr expStr = varStr <+> expStr
+    varDeclDecision True False varStr expStr = empty
+    arrayDimension a = case a of
+        ArrayDecl Nothing t -> let a = arrayDimension t in if a > 3 then error "Dynamic array with dimension > 4 is not supported." else 1 + arrayDimension t
+        ArrayDecl _ _ -> error "Mixed dynamic array and static array are not supported."
+        _ -> 0
+
+tvar2C f _ _ _ (OperatorDeclaration op (Identifier i _) inline ret params body) = do
+    r <- op2CTyped op (extractTypes params)
+    fun2C f i (FunctionDeclaration r inline False ret params body)
+
+
+op2CTyped :: String -> [TypeDecl] -> State RenderState Identifier
+op2CTyped op t = do
+    t' <- liftM (render . hcat . punctuate (char '_') . map (\t -> t empty)) $ mapM type2C t
+    bt <- gets lastType
+    return $ Identifier (t' ++ "_op_" ++ opStr) bt
+    where
+    opStr = case op of
+                    "+" -> "add"
+                    "-" -> "sub"
+                    "*" -> "mul"
+                    "/" -> "div"
+                    "/(float)" -> "div"
+                    "=" -> "eq"
+                    "<" -> "lt"
+                    ">" -> "gt"
+                    "<>" -> "neq"
+                    _ -> error $ "op2CTyped: unknown op '" ++ op ++ "'"
+
+extractTypes :: [TypeVarDeclaration] -> [TypeDecl]
+extractTypes = concatMap f
+    where
+        f (VarDeclaration _ _ (ids, t) _) = replicate (length ids) t
+        f a = error $ "extractTypes: can't extract from " ++ show a
+
+initExpr2C, initExpr2C' :: InitExpression -> State RenderState Doc
+initExpr2C (InitArray values) = liftM (braces . vcat . punctuate comma) $ mapM initExpr2C values
+initExpr2C a = initExpr2C' a
+initExpr2C' InitNull = return $ text "NULL"
+initExpr2C' (InitAddress expr) = do
+    ie <- initExpr2C' expr
+    lt <- gets lastType
+    case lt of
+        BTFunction True _ _ -> return $ text "&" <> ie -- <> text "__vars"
+        _ -> return $ text "&" <> ie
+initExpr2C' (InitPrefixOp op expr) = liftM (text (op2C op) <>) (initExpr2C' expr)
+initExpr2C' (InitBinOp op expr1 expr2) = do
+    e1 <- initExpr2C' expr1
+    e2 <- initExpr2C' expr2
+    return $ parens $ e1 <+> text (op2C op) <+> e2
+initExpr2C' (InitNumber s) = do
+								modify(\s -> s{lastType = (BTInt True)})
+								return $ text s
+initExpr2C' (InitFloat s) = return $ text s
+initExpr2C' (InitHexNumber s) = return $ text "0x" <> (text . map toLower $ s)
+initExpr2C' (InitString [a]) = return . quotes $ text [a]
+initExpr2C' (InitString s) = return $ strInit s
+initExpr2C' (InitChar a) = return $ quotes $ text "\\x" <> text (showHex (read a) "")
+initExpr2C' (InitReference i) = id2C IOLookup i
+initExpr2C' (InitRecord fields) = do
+    (fs :: [Doc]) <- mapM (\(Identifier a _, b) -> liftM (text "." <> text a <+> equals <+>) $ initExpr2C b) fields
+    return $ lbrace $+$ (nest 4 . vcat . punctuate comma $ fs) $+$ rbrace
+initExpr2C' (InitArray [value]) = initExpr2C value
+initExpr2C' r@(InitRange (Range i@(Identifier i' _))) = do
+    id2C IOLookup i
+    t <- gets lastType
+    case t of
+         BTEnum s -> return . int $ length s
+         BTInt _ -> case i' of
+                       "byte" -> return $ int 256
+                       _ -> error $ "InitRange identifier: " ++ i'
+         _ -> error $ "InitRange: " ++ show r
+initExpr2C' (InitRange (RangeFromTo (InitNumber "0") r)) = initExpr2C $ BuiltInFunction "succ" [r]
+initExpr2C' (InitRange (RangeFromTo (InitChar "0") (InitChar r))) = initExpr2C $ BuiltInFunction "succ" [InitNumber r]
+initExpr2C' (InitRange a) = error $ show a --return $ text "<<range>>"
+initExpr2C' (InitSet []) = return $ text "0"
+initExpr2C' (InitSet a) = return $ text "<<set>>"
+initExpr2C' (BuiltInFunction "low" [InitReference e]) = return $
+    case e of
+         (Identifier "LongInt" _) -> int (-2^31)
+         (Identifier "SmallInt" _) -> int (-2^15)
+         _ -> error $ "BuiltInFunction 'low': " ++ show e
+initExpr2C' (BuiltInFunction "high" [e]) = do
+    initExpr2C e
+    t <- gets lastType
+    case t of
+         (BTArray i _ _) -> initExpr2C' $ BuiltInFunction "pred" [InitRange i]
+         a -> error $ "BuiltInFunction 'high': " ++ show a
+initExpr2C' (BuiltInFunction "succ" [BuiltInFunction "pred" [e]]) = initExpr2C' e
+initExpr2C' (BuiltInFunction "pred" [BuiltInFunction "succ" [e]]) = initExpr2C' e
+initExpr2C' (BuiltInFunction "succ" [e]) = liftM (<> text " + 1") $ initExpr2C' e
+initExpr2C' (BuiltInFunction "pred" [e]) = liftM (<> text " - 1") $ initExpr2C' e
+initExpr2C' b@(BuiltInFunction _ _) = error $ show b
+initExpr2C' a = error $ "initExpr2C: don't know how to render " ++ show a
+
+
+range2C :: InitExpression -> State RenderState [Doc]
+range2C (InitString [a]) = return [quotes $ text [a]]
+range2C (InitRange (Range i)) = liftM (flip (:) []) $ id2C IOLookup i
+range2C (InitRange (RangeFromTo (InitString [a]) (InitString [b]))) = return $ map (\i -> quotes $ text [i]) [a..b]
+range2C a = liftM (flip (:) []) $ initExpr2C a
+
+baseType2C :: String -> BaseType -> Doc
+baseType2C _ BTFloat = text "float"
+baseType2C _ BTBool = text "bool"
+baseType2C _ BTString = text "string255"
+baseType2C s a = error $ "baseType2C: " ++ show a ++ "\n" ++ s
+
+type2C :: TypeDecl -> State RenderState (Doc -> Doc)
+type2C (SimpleType i) = liftM (\i a -> i <+> a) $ id2C IOLookup i
+type2C t = do
+    r <- type2C' t
+    rt <- resolveType t
+    modify (\st -> st{lastType = rt})
+    return r
+    where
+    type2C' VoidType = return (text "void" <+>)
+    type2C' (String l) = return (text "string255" <+>)--return (text ("string" ++ show l) <+>)
+    type2C' (PointerTo (SimpleType i)) = do
+        i' <- id2C IODeferred i
+        lt <- gets lastType
+        case lt of
+             BTRecord _ _ -> return $ \a -> text "struct __" <> i' <+> text "*" <+> a
+             BTUnknown -> return $ \a -> text "struct __" <> i' <+> text "*" <+> a
+             _ -> return $ \a -> i' <+> text "*" <+> a
+    type2C' (PointerTo t) = liftM (\t a -> t (parens $ text "*" <> a)) $ type2C t
+    type2C' (RecordType tvs union) = do
+        t <- withState' f $ mapM (tvar2C False False True False) tvs
+        u <- unions
+        return $ \i -> text "struct __" <> i <+> lbrace $+$ nest 4 ((vcat . map (<> semi) . concat $ t) $$ u) $+$ rbrace <+> i
+        where
+            f s = s{currentUnit = ""}
+            unions = case union of
+                     Nothing -> return empty
+                     Just a -> do
+                         structs <- mapM struct2C a
+                         return $ text "union" $+$ braces (nest 4 $ vcat structs) <> semi
+            struct2C tvs = do
+                t <- withState' f $ mapM (tvar2C False False True False) tvs
+                return $ text "struct" $+$ braces (nest 4 (vcat . map (<> semi) . concat $ t)) <> semi
+    type2C' (RangeType r) = return (text "int" <+>)
+    type2C' (Sequence ids) = do
+        is <- mapM (id2C IOInsert . setBaseType bt) ids
+        return (text "enum" <+> (braces . vcat . punctuate comma . map (\(a, b) -> a <+> equals <+> text "0x" <> text (showHex b "")) $ zip is [0..]) <+>)
+        where
+            bt = BTEnum $ map (\(Identifier i _) -> map toLower i) ids
+    type2C' (ArrayDecl Nothing t) = type2C (PointerTo t)
+    type2C' (ArrayDecl (Just r) t) = do
+        t' <- type2C t
+        lt <- gets lastType
+        ft <- case lt of
+                -- BTFunction {} -> type2C (PointerTo t)
+                _ -> return t'
+        r' <- initExpr2C (InitRange r)
+        return $ \i -> ft i <> brackets r'
+    type2C' (Set t) = return (text "<<set>>" <+>)
+    type2C' (FunctionType returnType params) = do
+        t <- type2C returnType
+        p <- withState' id $ functionParams2C params
+        return (\i -> (t empty <> (parens $ text "*" <> i) <> parens p))
+    type2C' (DeriveType (InitBinOp _ _ i)) = type2C' (DeriveType i)
+    type2C' (DeriveType (InitPrefixOp _ i)) = type2C' (DeriveType i)
+    type2C' (DeriveType (InitNumber _)) = return (text "int" <+>)
+    type2C' (DeriveType (InitHexNumber _)) = return (text "int" <+>)
+    type2C' (DeriveType (InitFloat _)) = return (text "float" <+>)
+    type2C' (DeriveType (BuiltInFunction {})) = return (text "int" <+>)
+    type2C' (DeriveType (InitString {})) = return (text "string255" <+>)
+    type2C' (DeriveType r@(InitReference {})) = do
+        initExpr2C r
+        t <- gets lastType
+        return (baseType2C (show r) t <+>)
+    type2C' (DeriveType a) = error $ "Can't derive type from " ++ show a
+
+phrase2C :: Phrase -> State RenderState Doc
+phrase2C (Phrases p) = do
+    ps <- mapM phrase2C p
+    return $ text "{" $+$ (nest 4 . vcat $ ps) $+$ text "}"
+phrase2C (ProcCall f@(FunCall {}) []) = liftM (<> semi) $ ref2C f
+phrase2C (ProcCall ref []) = liftM (<> semi) $ ref2CF ref True
+phrase2C (ProcCall ref params) = error $ "ProcCall"{-do
+    r <- ref2C ref
+    ps <- mapM expr2C params
+    return $ r <> parens (hsep . punctuate (char ',') $ ps) <> semi -}
+phrase2C (IfThenElse (expr) phrase1 mphrase2) = do
+    e <- expr2C expr
+    p1 <- (phrase2C . wrapPhrase) phrase1
+    el <- elsePart
+    return $
+        text "if" <> parens e $+$ p1 $+$ el
+    where
+    elsePart | isNothing mphrase2 = return $ empty
+             | otherwise = liftM (text "else" $$) $ (phrase2C . wrapPhrase) (fromJust mphrase2)
+phrase2C asgn@(Assignment ref expr) = do
+    r <- ref2C ref
+    t <- gets lastType
+    case (t, expr) of
+        (BTFunction {}, (Reference r')) -> do
+            e <- ref2C r'
+            return $ r <+> text "=" <+> e <> semi
+        (BTString, _) -> do
+            e <- expr2C expr
+            lt <- gets lastType
+            case lt of
+                -- assume pointer to char for simplicity
+                BTPointerTo _ -> do
+                    e <- expr2C $ Reference $ FunCall [Reference $ RefExpression expr] (SimpleReference (Identifier "pchar2str" BTUnknown))
+                    return $ r <+> text "=" <+> e <> semi
+                BTString -> do
+                    e <- expr2C expr
+                    return $ r <+> text "=" <+> e <> semi
+                _ -> error $ "Assignment to string from " ++ show asgn
+        (BTArray _ _ _, _) -> do
+            case expr of
+                Reference er -> do
+                    exprRef <- ref2C er
+                    exprT <- gets lastType
+                    case exprT of
+                        BTArray RangeInfinite _ _ ->
+                            return $ text "FIXME: assign a dynamic array to an array"
+                        BTArray _ _ _ -> phrase2C $
+                                ProcCall (FunCall
+                                    [
+                                    Reference $ ref
+                                    , Reference $ RefExpression expr
+                                    , Reference $ FunCall [expr] (SimpleReference (Identifier "sizeof" BTUnknown))
+                                    ]
+                                    (SimpleReference (Identifier "memcpy" BTUnknown))
+                                    ) []
+                        _ -> return $ text "FIXME: assign a non-specific value to an array"
+
+                _ -> return $ text "FIXME: dynamic array assignment 2"
+        _ -> do
+            e <- expr2C expr
+            return $ r <+> text "=" <+> e <> semi
+phrase2C (WhileCycle expr phrase) = do
+    e <- expr2C expr
+    p <- phrase2C $ wrapPhrase phrase
+    return $ text "while" <> parens e $$ p
+phrase2C (SwitchCase expr cases mphrase) = do
+    e <- expr2C expr
+    cs <- mapM case2C cases
+    d <- dflt
+    return $
+        text "switch" <> parens e $+$ braces (nest 4 . vcat $ cs ++ d)
+    where
+    case2C :: ([InitExpression], Phrase) -> State RenderState Doc
+    case2C (e, p) = do
+        ies <- mapM range2C e
+        ph <- phrase2C p
+        return $
+             vcat (map (\i -> text "case" <+> i <> colon) . concat $ ies) <> nest 4 (ph $+$ text "break;")
+    dflt | isNothing mphrase = return [text "default: break;"] -- avoid compiler warning
+         | otherwise = do
+             ph <- mapM phrase2C $ fromJust mphrase
+             return [text "default:" <+> nest 4 (vcat ph)]
+
+phrase2C wb@(WithBlock ref p) = do
+    r <- ref2C ref
+    t <- gets lastType
+    case t of
+        (BTRecord _ rs) -> withRecordNamespace (render r ++ ".") (rec2Records rs) $ phrase2C $ wrapPhrase p
+        a -> do
+            error $ "'with' block referencing non-record type " ++ show a ++ "\n" ++ show wb
+phrase2C (ForCycle i' e1' e2' p up) = do
+    i <- id2C IOLookup i'
+    iType <- gets lastIdTypeDecl
+    e1 <- expr2C e1'
+    e2 <- expr2C e2'
+    let inc = if up then "inc" else "dec"
+    let add = if up then "+ 1" else "- 1"
+    let iEnd = i <> text "__end__"
+    ph <- phrase2C . appendPhrase (BuiltInFunctionCall [Reference $ SimpleReference i'] (SimpleReference (Identifier inc BTUnknown))) $ wrapPhrase p
+    return . braces $
+        i <+> text "=" <+> e1 <> semi
+        $$
+        iType <+> iEnd <+> text "=" <+> e2 <> semi
+        $$ 
+        text "if" <+> (parens $ i <+> text (if up then "<=" else ">=") <+> iEnd) <+> text "do" <+> ph <+>
+        text "while" <> parens (i <+> text "!=" <+> iEnd <+> text add) <> semi
+    where
+        appendPhrase p (Phrases ps) = Phrases $ ps ++ [p]
+phrase2C (RepeatCycle e' p') = do
+    e <- expr2C e'
+    p <- phrase2C (Phrases p')
+    return $ text "do" <+> p <+> text "while" <> parens (text "!" <> parens e) <> semi
+
+phrase2C NOP = return $ text ";"
+
+phrase2C (BuiltInFunctionCall [] (SimpleReference (Identifier "exit" BTUnknown))) = do
+    f <- gets currentFunctionResult
+    if null f then
+        return $ text "return" <> semi
+        else
+        return $ text "return" <+> text f <> semi
+phrase2C (BuiltInFunctionCall [] (SimpleReference (Identifier "break" BTUnknown))) = return $ text "break" <> semi
+phrase2C (BuiltInFunctionCall [] (SimpleReference (Identifier "continue" BTUnknown))) = return $ text "continue" <> semi
+phrase2C (BuiltInFunctionCall [e] (SimpleReference (Identifier "exit" BTUnknown))) = liftM (\e -> text "return" <+> e <> semi) $ expr2C e
+phrase2C (BuiltInFunctionCall [e] (SimpleReference (Identifier "dec" BTUnknown))) = liftM (\e -> text "--" <> e <> semi) $ expr2C e
+phrase2C (BuiltInFunctionCall [e1, e2] (SimpleReference (Identifier "dec" BTUnknown))) = liftM2 (\a b -> a <> text " -= " <> b <> semi) (expr2C e1) (expr2C e2)
+phrase2C (BuiltInFunctionCall [e] (SimpleReference (Identifier "inc" BTUnknown))) = liftM (\e -> text "++" <> e <> semi) $ expr2C e
+phrase2C (BuiltInFunctionCall [e1, e2] (SimpleReference (Identifier "inc" BTUnknown))) = liftM2 (\a b -> a <+> text "+=" <+> b <> semi) (expr2C e1) (expr2C e2)
+phrase2C a = error $ "phrase2C: " ++ show a
+
+wrapPhrase p@(Phrases _) = p
+wrapPhrase p = Phrases [p]
+
+expr2C :: Expression -> State RenderState Doc
+expr2C (Expression s) = return $ text s
+expr2C b@(BinOp op expr1 expr2) = do
+    e1 <- expr2C expr1
+    t1 <- gets lastType
+    e2 <- expr2C expr2
+    t2 <- gets lastType
+    case (op2C op, t1, t2) of
+        ("+", BTString, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strconcat" (BTFunction False [(False, t1), (False, t2)] BTString))
+        ("+", BTString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strappend" (BTFunction False [(False, t1), (False, t2)] BTString))
+        ("+", BTChar, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strprepend" (BTFunction False [(False, t1), (False, t2)] BTString))
+        ("+", BTChar, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_chrconcat" (BTFunction False [(False, t1), (False, t2)] BTString))
+        ("==", BTString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strcomparec" (BTFunction False [(False, t1), (False, t2)] BTBool))
+
+        -- for function/procedure comparision
+        ("==", BTVoid, _) -> procCompare expr1 expr2 "=="
+        ("==", BTFunction _ _ _, _) -> procCompare expr1 expr2 "=="
+
+        ("!=", BTVoid, _) -> procCompare expr1 expr2 "!="
+        ("!=", BTFunction _ _ _, _) -> procCompare expr1 expr2 "!="
+
+        ("==", BTString, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strcompare" (BTFunction False [(False, t1), (False, t2)] BTBool))
+        ("!=", BTString, _) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strncompare" (BTFunction False [(False, t1), (False, t2)] BTBool))
+        ("&", BTBool, _) -> return $ parens e1 <+> text "&&" <+> parens e2
+        ("|", BTBool, _) -> return $ parens e1 <+> text "||" <+> parens e2
+        (_, BTRecord t1 _, BTRecord t2 _) -> do
+            i <- op2CTyped op [SimpleType (Identifier t1 undefined), SimpleType (Identifier t2 undefined)]
+            ref2C $ FunCall [expr1, expr2] (SimpleReference i)
+        (_, BTRecord t1 _, BTInt _) -> do
+            -- aw, "LongInt" here is hwengine-specific hack
+            i <- op2CTyped op [SimpleType (Identifier t1 undefined), SimpleType (Identifier "LongInt" undefined)]
+            ref2C $ FunCall [expr1, expr2] (SimpleReference i)
+        ("in", _, _) ->
+            case expr2 of
+                 SetExpression set -> do
+                     ids <- mapM (id2C IOLookup) set
+                     modify(\s -> s{lastType = BTBool})
+                     return . parens . hcat . punctuate (text " || ") . map (\i -> parens $ e1 <+> text "==" <+> i) $ ids
+                 _ -> error "'in' against not set expression"
+        (o, _, _) | o `elem` boolOps -> do
+                        modify(\s -> s{lastType = BTBool})
+                        return $ parens e1 <+> text o <+> parens e2
+                  | otherwise -> do
+                        o' <- return $ case o of
+                            "/(float)" -> text "/(float)" -- pascal returns real value
+                            _ -> text o
+                        e1' <- return $ case (o, t1, t2) of
+                                ("-", BTInt False, BTInt False) -> parens $ text "(int64_t)" <+> parens e1
+                                _ -> parens e1
+                        e2' <- return $ case (o, t1, t2) of
+                                ("-", BTInt False, BTInt False) -> parens $ text "(int64_t)" <+> parens e2
+                                _ -> parens e2
+                        return $ e1' <+> o' <+> e2'
+    where
+        boolOps = ["==", "!=", "<", ">", "<=", ">="]
+        procCompare expr1 expr2 op =
+            case (expr1, expr2) of
+                (Reference r1, Reference r2) -> do
+                    id1 <- ref2C r1
+                    id2 <- ref2C r2
+                    return $ (parens id1) <+> text op <+> (parens id2)
+                (_, _) -> error $ "Two non reference type vars are compared but they have type of BTVoid or BTFunction\n" ++ show expr1 ++ "\n" ++ show expr2
+
+expr2C (NumberLiteral s) = do
+    modify(\s -> s{lastType = BTInt True})
+    return $ text s
+expr2C (FloatLiteral s) = return $ text s
+expr2C (HexNumber s) = return $ text "0x" <> (text . map toLower $ s)
+{-expr2C (StringLiteral [a]) = do
+    modify(\s -> s{lastType = BTChar})
+    return . quotes . text $ escape a
+    where
+        escape '\'' = "\\\'"
+        escape a = [a]-}
+expr2C (StringLiteral s) = addStringConst s
+expr2C (PCharLiteral s) = return . doubleQuotes $ text s
+expr2C (Reference ref) = do
+   isfunc <- gets isFunctionType
+   modify(\s -> s{isFunctionType = False}) -- reset
+   if isfunc then ref2CF ref False else ref2CF ref True
+expr2C (PrefixOp op expr) = do
+    e <- expr2C expr
+    lt <- gets lastType
+    case lt of
+        BTRecord t _ -> do
+            i <- op2CTyped op [SimpleType (Identifier t undefined)]
+            ref2C $ FunCall [expr] (SimpleReference i)
+        BTBool -> do
+            o <- return $ case op of
+                     "not" -> text "!"
+                     _ -> text (op2C op)
+            return $ o <> parens e
+        _ -> return $ text (op2C op) <> parens e
+expr2C Null = return $ text "NULL"
+expr2C (CharCode a) = do
+    modify(\s -> s{lastType = BTChar})
+    return $ quotes $ text "\\x" <> text (showHex (read a) "")
+expr2C (HexCharCode a) = if length a <= 2 then return $ quotes $ text "\\x" <> text (map toLower a) else expr2C $ HexNumber a
+expr2C (SetExpression ids) = mapM (id2C IOLookup) ids >>= return . parens . hcat . punctuate (text " | ")
+
+expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "low" _))) = do
+    e' <- liftM (map toLower . render) $ expr2C e
+    lt <- gets lastType
+    case lt of
+         BTEnum a -> return $ int 0
+         BTInt _ -> case e' of
+                  "longint" -> return $ int (-2147483648)
+         BTArray {} -> return $ int 0
+         _ -> error $ "BuiltInFunCall 'low' from " ++ show e ++ "\ntype: " ++ show lt
+expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "high" _))) = do
+    e' <- liftM (map toLower . render) $ expr2C e
+    lt <- gets lastType
+    case lt of
+         BTEnum a -> return . int $ length a - 1
+         BTInt _ -> case e' of
+                  "longint" -> return $ int (2147483647)
+         BTString -> return $ int 255
+         BTArray (RangeFromTo _ n) _ _ -> initExpr2C n
+         _ -> error $ "BuiltInFunCall 'high' from " ++ show e ++ "\ntype: " ++ show lt
+expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "ord" _))) = liftM parens $ expr2C e
+expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "succ" _))) = liftM (<> text " + 1") $ expr2C e
+expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "pred" _))) = do
+    e'<- expr2C e
+    return $ text "(int)" <> parens e' <> text " - 1"
+expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "length" _))) = do
+    e' <- expr2C e
+    lt <- gets lastType
+    modify (\s -> s{lastType = BTInt True})
+    case lt of
+         BTString -> return $ text "fpcrtl_Length" <> parens e'
+         BTArray RangeInfinite _ _ -> error $ "length() called on variable size array " ++ show e'
+         BTArray (RangeFromTo _ n) _ _ -> initExpr2C (BuiltInFunction "succ" [n])
+         _ -> error $ "length() called on " ++ show lt
+expr2C (BuiltInFunCall params ref) = do
+    r <- ref2C ref
+    t <- gets lastType
+    ps <- mapM expr2C params
+    case t of
+        BTFunction _ _ t' -> do
+            modify (\s -> s{lastType = t'})
+        _ -> error $ "BuiltInFunCall lastType: " ++ show t
+    return $
+        r <> parens (hsep . punctuate (char ',') $ ps)
+expr2C a = error $ "Don't know how to render " ++ show a
+
+ref2CF :: Reference -> Bool -> State RenderState Doc
+ref2CF (SimpleReference name) addParens = do
+    i <- id2C IOLookup name
+    t <- gets lastType
+    case t of
+         BTFunction _ _ rt -> do
+             modify(\s -> s{lastType = rt})
+             return $ if addParens then i <> parens empty else i --xymeng: removed parens
+         _ -> return $ i
+ref2CF r@(RecordField (SimpleReference _) (SimpleReference _)) addParens = do
+    i <- ref2C r
+    t <- gets lastType
+    case t of
+         BTFunction _ _ rt -> do
+             modify(\s -> s{lastType = rt})
+             return $ if addParens then i <> parens empty else i 
+         _ -> return $ i
+ref2CF r _ = ref2C r
+
+ref2C :: Reference -> State RenderState Doc
+-- rewrite into proper form
+ref2C (RecordField ref1 (ArrayElement exprs ref2)) = ref2C $ ArrayElement exprs (RecordField ref1 ref2)
+ref2C (RecordField ref1 (Dereference ref2)) = ref2C $ Dereference (RecordField ref1 ref2)
+ref2C (RecordField ref1 (RecordField ref2 ref3)) = ref2C $ RecordField (RecordField ref1 ref2) ref3
+ref2C (RecordField ref1 (FunCall params ref2)) = ref2C $ FunCall params (RecordField ref1 ref2)
+ref2C (ArrayElement (a:b:xs) ref) = ref2C $ ArrayElement (b:xs) (ArrayElement [a] ref)
+-- conversion routines
+ref2C ae@(ArrayElement [expr] ref) = do
+    e <- expr2C expr
+    r <- ref2C ref
+    t <- gets lastType
+    case t of
+         (BTArray _ _ t') -> modify (\st -> st{lastType = t'})
+--         (BTFunctionReturn _ (BTArray _ _ t')) -> modify (\st -> st{lastType = t'})
+--         (BTFunctionReturn _ (BTString)) -> modify (\st -> st{lastType = BTChar})
+         (BTString) -> modify (\st -> st{lastType = BTChar})
+         (BTPointerTo t) -> do
+                t'' <- fromPointer (show t) =<< gets lastType
+                case t'' of
+                     BTChar -> modify (\st -> st{lastType = BTChar})
+                     a -> error $ "Getting element of " ++ show a ++ "\nReference: " ++ show ae
+         a -> error $ "Getting element of " ++ show a ++ "\nReference: " ++ show ae
+    case t of
+         BTString ->  return $ r <> text ".s" <> brackets e
+         _ -> return $ r <> brackets e
+ref2C (SimpleReference name) = id2C IOLookup name
+ref2C rf@(RecordField (Dereference ref1) ref2) = do
+    r1 <- ref2C ref1
+    t <- fromPointer (show ref1) =<< gets lastType
+    r2 <- case t of
+        BTRecord _ rs -> withRecordNamespace "" (rec2Records rs) $ ref2C ref2
+        BTUnit -> error "What??"
+        a -> error $ "dereferencing from " ++ show a ++ "\n" ++ show rf
+    return $
+        r1 <> text "->" <> r2
+ref2C rf@(RecordField ref1 ref2) = do
+    r1 <- ref2C ref1
+    t <- gets lastType
+    case t of
+        BTRecord _ rs -> do
+            r2 <- withRecordNamespace "" (rec2Records rs) $ ref2C ref2
+            return $ r1 <> text "." <> r2
+        BTUnit -> withLastIdNamespace $ ref2C ref2
+        a -> error $ "dereferencing from " ++ show a ++ "\n" ++ show rf
+ref2C d@(Dereference ref) = do
+    r <- ref2C ref
+    t <- fromPointer (show d) =<< gets lastType
+    modify (\st -> st{lastType = t})
+    return $ (parens $ text "*" <> r)
+ref2C f@(FunCall params ref) = do
+    r <- fref2C ref
+    t <- gets lastType
+    case t of
+        BTFunction _ bts t' -> do
+            ps <- liftM (parens . hsep . punctuate (char ',')) $ 
+                    if (length params) == (length bts) -- hot fix for pas2cSystem and pas2cRedo functions since they don't have params
+                    then 
+                        mapM expr2CHelper (zip params bts)
+                    else mapM expr2C params
+            modify (\s -> s{lastType = t'})
+            return $ r <> ps
+        _ -> case (ref, params) of
+                  (SimpleReference i, [p]) -> ref2C $ TypeCast i p
+                  _ -> error $ "ref2C FunCall erroneous type cast detected: " ++ show f ++ "\nType detected: " ++ show t ++ "\n" ++ show ref ++ "\n" ++ show params ++ "\n" ++ show t
+    where
+    fref2C (SimpleReference name) = id2C (IOLookupFunction $ length params) name
+    fref2C a = ref2C a
+    expr2CHelper :: (Expression, (Bool, BaseType)) -> State RenderState Doc
+    expr2CHelper (e, (_, BTFunction _ _ _)) = do
+        modify (\s -> s{isFunctionType = True})
+        expr2C e
+    expr2CHelper (e, (isVar, _)) = if isVar then liftM (((<>) $ text "&") . parens) $ (expr2C e) else expr2C e
+
+ref2C (Address ref) = do
+    r <- ref2C ref
+    lt <- gets lastType
+    case lt of
+        BTFunction True _ _ -> return $ text "&" <> parens r
+        _ -> return $ text "&" <> parens r
+ref2C (TypeCast t'@(Identifier i _) expr) = do
+    lt <- expr2C expr >> gets lastType
+    case (map toLower i, lt) of
+        ("pchar", BTString) -> ref2C $ FunCall [expr] (SimpleReference (Identifier "_pchar" $ BTPointerTo BTChar))
+        ("shortstring", BTPointerTo _) -> ref2C $ FunCall [expr] (SimpleReference (Identifier "pchar2str" $ BTString))
+        (a, _) -> do
+            e <- expr2C expr
+            t <- id2C IOLookup t'
+            return . parens $ parens t <> e
+ref2C (RefExpression expr) = expr2C expr
+
+
+op2C :: String -> String
+op2C "or" = "|"
+op2C "and" = "&"
+op2C "not" = "~"
+op2C "xor" = "^"
+op2C "div" = "/"
+op2C "mod" = "%"
+op2C "shl" = "<<"
+op2C "shr" = ">>"
+op2C "<>" = "!="
+op2C "=" = "=="
+op2C "/" = "/(float)"
+op2C a = a
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/pas2c/PascalBasics.hs	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,70 @@
+{-# LANGUAGE FlexibleContexts #-}
+module PascalBasics where
+
+import Text.Parsec.Combinator
+import Text.Parsec.Char
+import Text.Parsec.Prim
+import Text.Parsec.Token
+import Text.Parsec.Language
+import Data.Char
+
+builtin = ["succ", "pred", "low", "high", "ord", "inc", "dec", "exit", "break", "continue", "length"]
+
+pascalLanguageDef
+    = emptyDef
+    { commentStart   = "(*"
+    , commentEnd     = "*)"
+    , commentLine    = "//"
+    , nestedComments = False
+    , identStart     = letter <|> oneOf "_"
+    , identLetter    = alphaNum <|> oneOf "_"
+    , opLetter       = letter
+    , reservedNames  = [
+            "begin", "end", "program", "unit", "interface"
+            , "implementation", "and", "or", "xor", "shl"
+            , "shr", "while", "do", "repeat", "until", "case", "of"
+            , "type", "var", "const", "out", "array", "packed"
+            , "procedure", "function", "with", "for", "to"
+            , "downto", "div", "mod", "record", "set", "nil"
+            , "cdecl", "external", "if", "then", "else"
+            ] -- ++ builtin
+    , caseSensitive  = False
+    }
+
+preprocessorSwitch :: Stream s m Char => ParsecT s u m String
+preprocessorSwitch = do
+    try $ string "{$"
+    s <- manyTill (noneOf "\n") $ char '}'
+    return s
+
+caseInsensitiveString s = do
+    mapM_ (\a -> satisfy (\b -> toUpper a == toUpper b)) s <?> s
+    return s
+
+pas = patch $ makeTokenParser pascalLanguageDef
+    where
+    patch tp = tp {stringLiteral = stringL}
+
+comment = choice [
+        char '{' >> notFollowedBy (char '$') >> manyTill anyChar (try $ char '}')
+        , (try $ string "(*") >> manyTill anyChar (try $ string "*)")
+        , (try $ string "//") >> manyTill anyChar (try newline)
+        ]
+
+comments = do
+    spaces
+    skipMany $ do
+        preprocessorSwitch <|> comment
+        spaces
+
+stringL = do
+    (char '\'')
+    s <- (many $ noneOf "'")
+    (char '\'')
+    ss <- many $ do
+        (char '\'')
+        s' <- (many $ noneOf "'")
+        (char '\'')
+        return $ '\'' : s'
+    comments
+    return $ concat (s:ss)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/pas2c/PascalParser.hs	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,672 @@
+module PascalParser where
+
+import Text.Parsec
+import Text.Parsec.Char
+import Text.Parsec.Token
+import Text.Parsec.Language
+import Text.Parsec.Expr
+import Text.Parsec.Prim
+import Text.Parsec.Combinator
+import Text.Parsec.String
+import Control.Monad
+import Data.Maybe
+import Data.Char
+
+import PascalBasics
+import PascalUnitSyntaxTree
+
+knownTypes = ["shortstring", "ansistring", "char", "byte"]
+
+pascalUnit = do
+    comments
+    u <- choice [program, unit, systemUnit, redoUnit]
+    comments
+    return u
+
+iD = do
+    i <- liftM (flip Identifier BTUnknown) (identifier pas)
+    comments
+    return i
+
+unit = do
+    string "unit" >> comments
+    name <- iD
+    semi pas
+    comments
+    int <- interface
+    impl <- implementation
+    comments
+    return $ Unit name int impl Nothing Nothing
+
+
+reference = buildExpressionParser table term <?> "reference"
+    where
+    term = comments >> choice [
+        parens pas (liftM RefExpression expression >>= postfixes) >>= postfixes
+        , try $ typeCast >>= postfixes
+        , char '@' >> liftM Address reference >>= postfixes
+        , liftM SimpleReference iD >>= postfixes
+        ] <?> "simple reference"
+
+    table = [
+        ]
+
+    postfixes r = many postfix >>= return . foldl (flip ($)) r
+    postfix = choice [
+            parens pas (option [] parameters) >>= return . FunCall
+          , char '^' >> return Dereference
+          , (brackets pas) (commaSep1 pas $ expression) >>= return . ArrayElement
+          , (char '.' >> notFollowedBy (char '.')) >> liftM (flip RecordField) reference
+        ]
+
+    typeCast = do
+        t <- choice $ map (\s -> try $ caseInsensitiveString s >>= \i -> notFollowedBy alphaNum >> return i) knownTypes
+        e <- parens pas expression
+        comments
+        return $ TypeCast (Identifier t BTUnknown) e
+
+varsDecl1 = varsParser sepEndBy1
+varsDecl = varsParser sepEndBy
+varsParser m endsWithSemi = do
+    vs <- m (aVarDecl endsWithSemi) (semi pas)
+    return vs
+
+aVarDecl endsWithSemi = do
+    isVar <- liftM (== Just "var") $
+        if not endsWithSemi then
+            optionMaybe $ choice [
+                try $ string "var"
+                , try $ string "const"
+                , try $ string "out"
+                ]
+            else
+                return Nothing
+    comments
+    ids <- do
+        i <- (commaSep1 pas) $ (try iD <?> "variable declaration")
+        char ':'
+        return i
+    comments
+    t <- typeDecl <?> "variable type declaration"
+    comments
+    init <- option Nothing $ do
+        char '='
+        comments
+        e <- initExpression
+        comments
+        return (Just e)
+    return $ VarDeclaration isVar False (ids, t) init
+
+
+constsDecl = do
+    vs <- many1 (try (aConstDecl >>= \i -> semi pas >> return i) >>= \i -> comments >> return i)
+    comments
+    return vs
+    where
+    aConstDecl = do
+        comments
+        i <- iD
+        t <- optionMaybe $ do
+            char ':'
+            comments
+            t <- typeDecl
+            comments
+            return t
+        char '='
+        comments
+        e <- initExpression
+        comments
+        return $ VarDeclaration False (isNothing t) ([i], fromMaybe (DeriveType e) t) (Just e)
+
+typeDecl = choice [
+    char '^' >> typeDecl >>= return . PointerTo
+    , try (string "shortstring") >> return (String 255)
+    , try (string "string") >> optionMaybe (brackets pas $ integer pas) >>= return . String . fromMaybe 255
+    , try (string "ansistring") >> optionMaybe (brackets pas $ integer pas) >>= return . String . fromMaybe 255
+    , arrayDecl
+    , recordDecl
+    , setDecl
+    , functionType
+    , sequenceDecl >>= return . Sequence
+    , try iD >>= return . SimpleType
+    , rangeDecl >>= return . RangeType
+    ] <?> "type declaration"
+    where
+    arrayDecl = do
+        try $ do
+            optional $ (try $ string "packed") >> comments
+            string "array"
+        comments
+        r <- option [] $ do
+            char '['
+            r <- commaSep pas rangeDecl
+            char ']'
+            comments
+            return r
+        string "of"
+        comments
+        t <- typeDecl
+        if null r then
+            return $ ArrayDecl Nothing t
+            else
+            return $ foldr (\a b -> ArrayDecl (Just a) b) (ArrayDecl (Just $ head r) t) (tail r)
+    recordDecl = do
+        try $ do
+            optional $ (try $ string "packed") >> comments
+            string "record"
+        comments
+        vs <- varsDecl True
+        union <- optionMaybe $ do
+            string "case"
+            comments
+            iD
+            comments
+            string "of"
+            comments
+            many unionCase
+        string "end"
+        return $ RecordType vs union
+    setDecl = do
+        try $ string "set" >> space
+        comments
+        string "of"
+        comments
+        liftM Set typeDecl
+    unionCase = do
+        try $ commaSep pas $ (iD >> return ()) <|> (integer pas >> return ())
+        char ':'
+        comments
+        u <- parens pas $ varsDecl True
+        char ';'
+        comments
+        return u
+    sequenceDecl = (parens pas) $ (commaSep pas) (iD >>= \i -> optional (spaces >> char '=' >> spaces >> integer pas) >> return i)
+    functionType = do
+        fp <- try (string "function") <|> try (string "procedure")
+        comments
+        vs <- option [] $ parens pas $ varsDecl False
+        comments
+        ret <- if (fp == "function") then do
+            char ':'
+            comments
+            ret <- typeDecl
+            comments
+            return ret
+            else
+            return VoidType
+        optional $ try $ char ';' >> comments >> string "cdecl"
+        comments
+        return $ FunctionType ret vs
+
+typesDecl = many (aTypeDecl >>= \t -> comments >> return t)
+    where
+    aTypeDecl = do
+        i <- try $ do
+            i <- iD <?> "type declaration"
+            comments
+            char '='
+            return i
+        comments
+        t <- typeDecl
+        comments
+        semi pas
+        comments
+        return $ TypeDeclaration i t
+
+rangeDecl = choice [
+    try $ rangeft
+    , iD >>= return . Range
+    ] <?> "range declaration"
+    where
+    rangeft = do
+    e1 <- initExpression
+    string ".."
+    e2 <- initExpression
+    return $ RangeFromTo e1 e2
+
+typeVarDeclaration isImpl = (liftM concat . many . choice) [
+    varSection,
+    constSection,
+    typeSection,
+    funcDecl,
+    operatorDecl
+    ]
+    where
+
+    fixInit v = concat $ map (\x -> case x of
+                    VarDeclaration a b (ids, t) c ->
+                        let typeId = (Identifier ((\(Identifier i _) -> i) (head ids) ++ "_tt") BTUnknown) in
+                        let res =  [TypeDeclaration typeId t, VarDeclaration a b (ids, (SimpleType typeId)) c] in
+                        case t of
+                            RecordType _ _ -> res -- create a separated type declaration
+                            ArrayDecl _ _ -> res
+                            _ -> [x]
+                    _ -> error ("checkInit:\n" ++ (show v))) v
+
+    varSection = do
+        try $ string "var"
+        comments
+        v <- varsDecl1 True <?> "variable declaration"
+        comments
+        return $ fixInit v
+
+    constSection = do
+        try $ string "const"
+        comments
+        c <- constsDecl <?> "const declaration"
+        comments
+        return $ fixInit c
+
+    typeSection = do
+        try $ string "type"
+        comments
+        t <- typesDecl <?> "type declaration"
+        comments
+        return t
+
+    operatorDecl = do
+        try $ string "operator"
+        comments
+        i <- manyTill anyChar space
+        comments
+        vs <- parens pas $ varsDecl False
+        comments
+        rid <- iD
+        comments
+        char ':'
+        comments
+        ret <- typeDecl
+        comments
+        return ret
+        char ';'
+        comments
+        forward <- liftM isJust $ optionMaybe (try (string "forward;") >> comments)
+        inline <- liftM (any (== "inline;")) $ many functionDecorator
+        b <- if isImpl && (not forward) then
+                liftM Just functionBody
+                else
+                return Nothing
+        return $ [OperatorDeclaration i rid inline ret vs b]
+
+
+    funcDecl = do
+        fp <- try (string "function") <|> try (string "procedure")
+        comments
+        i <- iD
+        vs <- option [] $ parens pas $ varsDecl False
+        comments
+        ret <- if (fp == "function") then do
+            char ':'
+            comments
+            ret <- typeDecl
+            comments
+            return ret
+            else
+            return VoidType
+        char ';'
+        comments
+        forward <- liftM isJust $ optionMaybe (try (string "forward;") >> comments)
+        decorators <- many functionDecorator
+        let inline = any (== "inline;") decorators
+            overload = any (== "overload;") decorators
+        b <- if isImpl && (not forward) then
+                liftM Just functionBody
+                else
+                return Nothing
+        return $ [FunctionDeclaration i inline overload ret vs b]
+
+    functionDecorator = do
+        d <- choice [
+            try $ string "inline;"
+            , try $ caseInsensitiveString "cdecl;"
+            , try $ string "overload;"
+            , try $ string "export;"
+            , try $ string "varargs;"
+            , try (string "external") >> comments >> iD >> optional (string "name" >> comments >> stringLiteral pas)>> string ";"
+            ]
+        comments
+        return d
+
+
+program = do
+    string "program"
+    comments
+    name <- iD
+    (char ';')
+    comments
+    comments
+    u <- uses
+    comments
+    tv <- typeVarDeclaration True
+    comments
+    p <- phrase
+    comments
+    char '.'
+    comments
+    return $ Program name (Implementation u (TypesAndVars tv)) p
+
+interface = do
+    string "interface"
+    comments
+    u <- uses
+    comments
+    tv <- typeVarDeclaration False
+    comments
+    return $ Interface u (TypesAndVars tv)
+
+implementation = do
+    string "implementation"
+    comments
+    u <- uses
+    comments
+    tv <- typeVarDeclaration True
+    string "end."
+    comments
+    return $ Implementation u (TypesAndVars tv)
+
+expression = do
+    buildExpressionParser table term <?> "expression"
+    where
+    term = comments >> choice [
+        builtInFunction expression >>= \(n, e) -> return $ BuiltInFunCall e (SimpleReference (Identifier n BTUnknown))
+        , try (parens pas $ expression >>= \e -> notFollowedBy (comments >> char '.') >> return e)
+        , brackets pas (commaSep pas iD) >>= return . SetExpression
+        , try $ integer pas >>= \i -> notFollowedBy (char '.') >> (return . NumberLiteral . show) i
+        , float pas >>= return . FloatLiteral . show
+        , try $ integer pas >>= return . NumberLiteral . show
+        , try (string "_S" >> stringLiteral pas) >>= return . StringLiteral
+        , try (string "_P" >> stringLiteral pas) >>= return . PCharLiteral
+        , stringLiteral pas >>= return . strOrChar
+        , try (string "#$") >> many hexDigit >>= \c -> comments >> return (HexCharCode c)
+        , char '#' >> many digit >>= \c -> comments >> return (CharCode c)
+        , char '$' >> many hexDigit >>=  \h -> comments >> return (HexNumber h)
+        --, char '-' >> expression >>= return . PrefixOp "-"
+        , char '-' >> reference >>= return . PrefixOp "-" . Reference
+        , (try $ string "not" >> notFollowedBy comments) >> unexpected "'not'"
+        , try $ string "nil" >> return Null
+        , reference >>= return . Reference
+        ] <?> "simple expression"
+
+    table = [
+          [  Prefix (reservedOp pas "not">> return (PrefixOp "not"))
+           , Prefix (try (char '-') >> return (PrefixOp "-"))]
+           ,
+          [  Infix (char '*' >> return (BinOp "*")) AssocLeft
+           , Infix (char '/' >> return (BinOp "/")) AssocLeft
+           , Infix (try (string "div") >> return (BinOp "div")) AssocLeft
+           , Infix (try (string "mod") >> return (BinOp "mod")) AssocLeft
+           , Infix (try (string "in") >> return (BinOp "in")) AssocNone
+           , Infix (try $ string "and" >> return (BinOp "and")) AssocLeft
+           , Infix (try $ string "shl" >> return (BinOp "shl")) AssocLeft
+           , Infix (try $ string "shr" >> return (BinOp "shr")) AssocLeft
+          ]
+        , [  Infix (char '+' >> return (BinOp "+")) AssocLeft
+           , Infix (char '-' >> return (BinOp "-")) AssocLeft
+           , Infix (try $ string "or" >> return (BinOp "or")) AssocLeft
+           , Infix (try $ string "xor" >> return (BinOp "xor")) AssocLeft
+          ]
+        , [  Infix (try (string "<>") >> return (BinOp "<>")) AssocNone
+           , Infix (try (string "<=") >> return (BinOp "<=")) AssocNone
+           , Infix (try (string ">=") >> return (BinOp ">=")) AssocNone
+           , Infix (char '<' >> return (BinOp "<")) AssocNone
+           , Infix (char '>' >> return (BinOp ">")) AssocNone
+          ]
+        {-, [  Infix (try $ string "shl" >> return (BinOp "shl")) AssocNone
+             , Infix (try $ string "shr" >> return (BinOp "shr")) AssocNone
+          ]
+        , [
+             Infix (try $ string "or" >> return (BinOp "or")) AssocLeft
+           , Infix (try $ string "xor" >> return (BinOp "xor")) AssocLeft
+          ]-}
+        , [
+             Infix (char '=' >> return (BinOp "=")) AssocNone
+          ]
+        ]
+    strOrChar [a] = CharCode . show . ord $ a
+    strOrChar a = StringLiteral a
+
+phrasesBlock = do
+    try $ string "begin"
+    comments
+    p <- manyTill phrase (try $ string "end" >> notFollowedBy alphaNum)
+    comments
+    return $ Phrases p
+
+phrase = do
+    o <- choice [
+        phrasesBlock
+        , ifBlock
+        , whileCycle
+        , repeatCycle
+        , switchCase
+        , withBlock
+        , forCycle
+        , (try $ reference >>= \r -> string ":=" >> return r) >>= \r -> comments >> expression >>= return . Assignment r
+        , builtInFunction expression >>= \(n, e) -> return $ BuiltInFunctionCall e (SimpleReference (Identifier n BTUnknown))
+        , procCall
+        , char ';' >> comments >> return NOP
+        ]
+    optional $ char ';'
+    comments
+    return o
+
+ifBlock = do
+    try $ string "if" >> notFollowedBy (alphaNum <|> char '_')
+    comments
+    e <- expression
+    comments
+    string "then"
+    comments
+    o1 <- phrase
+    comments
+    o2 <- optionMaybe $ do
+        try $ string "else" >> space
+        comments
+        o <- option NOP phrase
+        comments
+        return o
+    return $ IfThenElse e o1 o2
+
+whileCycle = do
+    try $ string "while"
+    comments
+    e <- expression
+    comments
+    string "do"
+    comments
+    o <- phrase
+    return $ WhileCycle e o
+
+withBlock = do
+    try $ string "with" >> space
+    comments
+    rs <- (commaSep1 pas) reference
+    comments
+    string "do"
+    comments
+    o <- phrase
+    return $ foldr WithBlock o rs
+
+repeatCycle = do
+    try $ string "repeat" >> space
+    comments
+    o <- many phrase
+    string "until"
+    comments
+    e <- expression
+    comments
+    return $ RepeatCycle e o
+
+forCycle = do
+    try $ string "for" >> space
+    comments
+    i <- iD
+    comments
+    string ":="
+    comments
+    e1 <- expression
+    comments
+    up <- liftM (== Just "to") $
+            optionMaybe $ choice [
+                try $ string "to"
+                , try $ string "downto"
+                ]
+    --choice [string "to", string "downto"]
+    comments
+    e2 <- expression
+    comments
+    string "do"
+    comments
+    p <- phrase
+    comments
+    return $ ForCycle i e1 e2 p up
+
+switchCase = do
+    try $ string "case"
+    comments
+    e <- expression
+    comments
+    string "of"
+    comments
+    cs <- many1 aCase
+    o2 <- optionMaybe $ do
+        try $ string "else" >> notFollowedBy alphaNum
+        comments
+        o <- many phrase
+        comments
+        return o
+    string "end"
+    comments
+    return $ SwitchCase e cs o2
+    where
+    aCase = do
+        e <- (commaSep pas) $ (liftM InitRange rangeDecl <|> initExpression)
+        comments
+        char ':'
+        comments
+        p <- phrase
+        comments
+        return (e, p)
+
+procCall = do
+    r <- reference
+    p <- option [] $ (parens pas) parameters
+    return $ ProcCall r p
+
+parameters = (commaSep pas) expression <?> "parameters"
+
+functionBody = do
+    tv <- typeVarDeclaration True
+    comments
+    p <- phrasesBlock
+    char ';'
+    comments
+    return (TypesAndVars tv, p)
+
+uses = liftM Uses (option [] u)
+    where
+        u = do
+            string "uses"
+            comments
+            u <- (iD >>= \i -> comments >> return i) `sepBy1` (char ',' >> comments)
+            char ';'
+            comments
+            return u
+
+initExpression = buildExpressionParser table term <?> "initialization expression"
+    where
+    term = comments >> choice [
+        liftM (uncurry BuiltInFunction) $ builtInFunction initExpression
+        , try $ brackets pas (commaSep pas $ initExpression) >>= return . InitSet
+        , try $ parens pas (commaSep pas $ initExpression) >>= \ia -> when (null $ tail ia) mzero >> return (InitArray ia)
+        , try $ parens pas (sepEndBy recField (char ';' >> comments)) >>= return . InitRecord
+        , parens pas initExpression
+        , try $ integer pas >>= \i -> notFollowedBy (char '.') >> (return . InitNumber . show) i
+        , try $ float pas >>= return . InitFloat . show
+        , try $ integer pas >>= return . InitNumber . show
+        , stringLiteral pas >>= return . InitString
+        , char '#' >> many digit >>= \c -> comments >> return (InitChar c)
+        , char '$' >> many hexDigit >>= \h -> comments >> return (InitHexNumber h)
+        , char '@' >> initExpression >>= \c -> comments >> return (InitAddress c)
+        , try $ string "nil" >> return InitNull
+        , itypeCast
+        , iD >>= return . InitReference
+        ]
+
+    recField = do
+        i <- iD
+        spaces
+        char ':'
+        spaces
+        e <- initExpression
+        spaces
+        return (i ,e)
+
+    table = [
+          [
+             Prefix (char '-' >> return (InitPrefixOp "-"))
+            ,Prefix (try (string "not") >> return (InitPrefixOp "not"))
+          ]
+        , [  Infix (char '*' >> return (InitBinOp "*")) AssocLeft
+           , Infix (char '/' >> return (InitBinOp "/")) AssocLeft
+           , Infix (try (string "div") >> return (InitBinOp "div")) AssocLeft
+           , Infix (try (string "mod") >> return (InitBinOp "mod")) AssocLeft
+           , Infix (try $ string "and" >> return (InitBinOp "and")) AssocLeft
+           , Infix (try $ string "shl" >> return (InitBinOp "shl")) AssocNone
+           , Infix (try $ string "shr" >> return (InitBinOp "shr")) AssocNone
+          ]
+        , [  Infix (char '+' >> return (InitBinOp "+")) AssocLeft
+           , Infix (char '-' >> return (InitBinOp "-")) AssocLeft
+           , Infix (try $ string "or" >> return (InitBinOp "or")) AssocLeft
+           , Infix (try $ string "xor" >> return (InitBinOp "xor")) AssocLeft
+          ]
+        , [  Infix (try (string "<>") >> return (InitBinOp "<>")) AssocNone
+           , Infix (try (string "<=") >> return (InitBinOp "<=")) AssocNone
+           , Infix (try (string ">=") >> return (InitBinOp ">=")) AssocNone
+           , Infix (char '<' >> return (InitBinOp "<")) AssocNone
+           , Infix (char '>' >> return (InitBinOp ">")) AssocNone
+           , Infix (char '=' >> return (InitBinOp "=")) AssocNone
+          ]
+        {--, [  Infix (try $ string "and" >> return (InitBinOp "and")) AssocLeft
+           , Infix (try $ string "or" >> return (InitBinOp "or")) AssocLeft
+           , Infix (try $ string "xor" >> return (InitBinOp "xor")) AssocLeft
+          ]
+        , [  Infix (try $ string "shl" >> return (InitBinOp "shl")) AssocNone
+           , Infix (try $ string "shr" >> return (InitBinOp "shr")) AssocNone
+          ]--}
+        --, [Prefix (try (string "not") >> return (InitPrefixOp "not"))]
+        ]
+
+    itypeCast = do
+        t <- choice $ map (\s -> try $ caseInsensitiveString s >>= \i -> notFollowedBy alphaNum >> return i) knownTypes
+        i <- parens pas initExpression
+        comments
+        return $ InitTypeCast (Identifier t BTUnknown) i
+
+builtInFunction e = do
+    name <- choice $ map (\s -> try $ caseInsensitiveString s >>= \i -> notFollowedBy alphaNum >> return i) builtin
+    spaces
+    exprs <- option [] $ parens pas $ option [] $ commaSep1 pas $ e
+    spaces
+    return (name, exprs)
+
+systemUnit = do
+    string "system;"
+    comments
+    string "type"
+    comments
+    t <- typesDecl
+    string "var"
+    v <- varsDecl True
+    return $ System (t ++ v)
+
+redoUnit = do
+    string "redo;"
+    comments
+    string "type"
+    comments
+    t <- typesDecl
+    string "var"
+    v <- varsDecl True
+    return $ Redo (t ++ v)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/pas2c/PascalPreprocessor.hs	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,137 @@
+module PascalPreprocessor where
+
+import Text.Parsec
+import Control.Monad.IO.Class
+import Control.Monad
+import System.IO
+import qualified Data.Map as Map
+import Data.Char
+
+
+-- comments are removed
+comment = choice [
+        char '{' >> notFollowedBy (char '$') >> manyTill anyChar (try $ char '}') >> return ""
+        , (try $ string "(*") >> manyTill anyChar (try $ string "*)") >> return ""
+        , (try $ string "//") >> manyTill anyChar (try newline) >> return "\n"
+        ]
+
+
+initDefines = Map.fromList [
+    ("FPC", "")
+    , ("PAS2C", "")
+--    , ("WEBGL", "")
+--    , ("AI_MAINTHREAD", "")
+    , ("ENDIAN_LITTLE", "")
+    ]
+
+preprocess :: String -> String -> String -> IO String
+preprocess inputPath alternateInputPath fn = do
+    r <- runParserT (preprocessFile (inputPath ++ fn)) (initDefines, [True]) "" ""
+    case r of
+         (Left a) -> do
+             hPutStrLn stderr (show a)
+             return ""
+         (Right a) -> return a
+
+    where
+    preprocessFile fn = do
+        f <- liftIO (readFile fn)
+        setInput f
+        preprocessor
+
+    preprocessor, codeBlock, switch :: ParsecT String (Map.Map String String, [Bool]) IO String
+
+    preprocessor = chainr codeBlock (return (++)) ""
+
+    codeBlock = do
+        s <- choice [
+            switch
+            , comment
+            , char '\'' >> many (noneOf "'\n") >>= \s -> char '\'' >> return ('\'' : s ++ "'")
+            , identifier >>= replace
+            , noneOf "{" >>= \a -> return [a]
+            ]
+        (_, ok) <- getState
+        return $ if and ok then s else ""
+
+    --otherChar c = c `notElem` "{/('_" && not (isAlphaNum c)
+    identifier = do
+        c <- letter <|> oneOf "_"
+        s <- many (alphaNum <|> oneOf "_")
+        return $ c:s
+
+    switch = do
+        try $ string "{$"
+        s <- choice [
+            include
+            , ifdef
+            , if'
+            , elseSwitch
+            , endIf
+            , define
+            , unknown
+            ]
+        return s
+
+    include = do
+        try $ string "INCLUDE"
+        spaces
+        (char '"')
+        fn <- many1 $ noneOf "\"\n"
+        char '"'
+        spaces
+        char '}'
+        f <- liftIO (readFile (inputPath ++ fn) `catch` (\exc -> readFile (alternateInputPath ++ fn) `catch` error ("File not found: " ++ fn)))
+        c <- getInput
+        setInput $ f ++ c
+        return ""
+
+    ifdef = do
+        s <- try (string "IFDEF") <|> try (string "IFNDEF")
+        let f = if s == "IFNDEF" then not else id
+
+        spaces
+        d <- identifier
+        spaces
+        char '}'
+
+        updateState $ \(m, b) ->
+            (m, (f $ d `Map.member` m) : b)
+
+        return ""
+
+    if' = do
+        s <- try (string "IF" >> notFollowedBy alphaNum)
+
+        manyTill anyChar (char '}')
+        --char '}'
+
+        updateState $ \(m, b) ->
+            (m, False : b)
+
+        return ""
+
+    elseSwitch = do
+        try $ string "ELSE}"
+        updateState $ \(m, b:bs) -> (m, (not b):bs)
+        return ""
+    endIf = do
+        try $ string "ENDIF}"
+        updateState $ \(m, b:bs) -> (m, bs)
+        return ""
+    define = do
+        try $ string "DEFINE"
+        spaces
+        i <- identifier
+        d <- ((string ":=" >> return ()) <|> spaces) >> many (noneOf "}")
+        char '}'
+        updateState $ \(m, b) -> (if (and b) && (head i /= '_') then Map.insert i d m else m, b)
+        return ""
+    replace s = do
+        (m, _) <- getState
+        return $ Map.findWithDefault s s m
+
+    unknown = do
+        fn <- many1 $ noneOf "}\n"
+        char '}'
+        return $ "{$" ++ fn ++ "}"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/pas2c/PascalUnitSyntaxTree.hs	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,119 @@
+module PascalUnitSyntaxTree where
+
+import Data.Maybe
+import Data.Char
+
+data PascalUnit =
+    Program Identifier Implementation Phrase
+    | Unit Identifier Interface Implementation (Maybe Initialize) (Maybe Finalize)
+    | System [TypeVarDeclaration]
+    | Redo [TypeVarDeclaration]
+    deriving Show
+data Interface = Interface Uses TypesAndVars
+    deriving Show
+data Implementation = Implementation Uses TypesAndVars
+    deriving Show
+data Identifier = Identifier String BaseType
+    deriving Show
+data TypesAndVars = TypesAndVars [TypeVarDeclaration]
+    deriving Show
+data TypeVarDeclaration = TypeDeclaration Identifier TypeDecl
+    | VarDeclaration Bool Bool ([Identifier], TypeDecl) (Maybe InitExpression)
+    | FunctionDeclaration Identifier Bool Bool TypeDecl [TypeVarDeclaration] (Maybe (TypesAndVars, Phrase))
+    | OperatorDeclaration String Identifier Bool TypeDecl [TypeVarDeclaration] (Maybe (TypesAndVars, Phrase))
+    deriving Show
+data TypeDecl = SimpleType Identifier
+    | RangeType Range
+    | Sequence [Identifier]
+    | ArrayDecl (Maybe Range) TypeDecl
+    | RecordType [TypeVarDeclaration] (Maybe [[TypeVarDeclaration]])
+    | PointerTo TypeDecl
+    | String Integer
+    | Set TypeDecl
+    | FunctionType TypeDecl [TypeVarDeclaration]
+    | DeriveType InitExpression
+    | VoidType
+    | VarParamType TypeDecl -- this is a hack
+    deriving Show
+data Range = Range Identifier
+           | RangeFromTo InitExpression InitExpression
+           | RangeInfinite
+    deriving Show
+data Initialize = Initialize String
+    deriving Show
+data Finalize = Finalize String
+    deriving Show
+data Uses = Uses [Identifier]
+    deriving Show
+data Phrase = ProcCall Reference [Expression]
+        | IfThenElse Expression Phrase (Maybe Phrase)
+        | WhileCycle Expression Phrase
+        | RepeatCycle Expression [Phrase]
+        | ForCycle Identifier Expression Expression Phrase Bool -- The last Boolean indicates wether it's up or down counting
+        | WithBlock Reference Phrase
+        | Phrases [Phrase]
+        | SwitchCase Expression [([InitExpression], Phrase)] (Maybe [Phrase])
+        | Assignment Reference Expression
+        | BuiltInFunctionCall [Expression] Reference
+        | NOP
+    deriving Show
+data Expression = Expression String
+    | BuiltInFunCall [Expression] Reference
+    | PrefixOp String Expression
+    | PostfixOp String Expression
+    | BinOp String Expression Expression
+    | StringLiteral String
+    | PCharLiteral String
+    | CharCode String
+    | HexCharCode String
+    | NumberLiteral String
+    | FloatLiteral String
+    | HexNumber String
+    | Reference Reference
+    | SetExpression [Identifier]
+    | Null
+    deriving Show
+data Reference = ArrayElement [Expression] Reference
+    | FunCall [Expression] Reference
+    | TypeCast Identifier Expression
+    | SimpleReference Identifier
+    | Dereference Reference
+    | RecordField Reference Reference
+    | Address Reference
+    | RefExpression Expression
+    deriving Show
+data InitExpression = InitBinOp String InitExpression InitExpression
+    | InitPrefixOp String InitExpression
+    | InitReference Identifier
+    | InitArray [InitExpression]
+    | InitRecord [(Identifier, InitExpression)]
+    | InitFloat String
+    | InitNumber String
+    | InitHexNumber String
+    | InitString String
+    | InitChar String
+    | BuiltInFunction String [InitExpression]
+    | InitSet [InitExpression]
+    | InitAddress InitExpression
+    | InitNull
+    | InitRange Range
+    | InitTypeCast Identifier InitExpression
+    deriving Show
+
+data BaseType = BTUnknown
+    | BTChar
+    | BTString
+    | BTInt Bool -- second param indicates whether signed or not
+    | BTBool
+    | BTFloat
+    | BTRecord String [(String, BaseType)]
+    | BTArray Range BaseType BaseType
+    | BTFunction Bool [(Bool, BaseType)] BaseType -- (Bool, BaseType), Bool indiciates whether var or not
+    | BTPointerTo BaseType
+    | BTUnresolved String
+    | BTSet BaseType
+    | BTEnum [String]
+    | BTVoid
+    | BTUnit
+    | BTVarParam BaseType
+    deriving Show
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/pas2c/unitCycles.hs	Sun Jun 09 12:22:53 2013 +0200
@@ -0,0 +1,46 @@
+module Main where
+
+import PascalParser
+import System
+import Control.Monad
+import Data.Either
+import Data.List
+import Data.Graph
+import Data.Maybe
+
+unident :: Identificator -> String
+unident (Identificator s) = s
+
+extractUnits :: PascalUnit -> (String, [String])
+extractUnits (Program (Identificator name) (Implementation (Uses idents) _ _) _) = ("program " ++ name, map unident idents)
+extractUnits (Unit (Identificator name) (Interface (Uses idents1) _) (Implementation (Uses idents2) _ _) _ _) = (name, map unident $ idents1 ++ idents2)
+
+f :: [(String, [String])] -> String
+f = unlines . map showSCC . stronglyConnComp . map (\(a, b) -> (a, a, b))
+    where
+    showSCC (AcyclicSCC v) = v
+    showSCC (CyclicSCC vs) = intercalate ", " vs
+
+myf :: [(String, [String])] -> String
+myf d = unlines . map (findCycle . fst) $ d
+    where
+    findCycle :: String -> String
+    findCycle searched = searched ++ ": " ++ (intercalate ", " $ fc searched [])
+        where
+        fc :: String -> [String] -> [String]
+        fc curSearch visited = let uses = curSearch `lookup` d; res = dropWhile null . map t $ fromJust uses in if isNothing uses || null res then [] else head res
+            where
+            t u =
+                if u == searched then
+                    [u]
+                    else
+                    if u `elem` visited then
+                        []
+                        else
+                        let chain = fc u (u:visited) in if null chain then [] else u:chain
+
+
+main = do
+    fileNames <- getArgs
+    files <- mapM readFile fileNames
+    putStrLn . myf . map extractUnits . rights . map parsePascalUnit $ files