merge cmake_pascal branch in default
authorkoda
Thu, 13 Jun 2013 22:27:23 +0200
changeset 9224 bce8cf41d666
parent 9223 71fc5893071c (current diff)
parent 8869 11438c0bd46b (diff)
child 9225 d8d929f92633
merge cmake_pascal branch in default
CMakeLists.txt
cmake_modules/FindFreePascal.cmake
cmake_modules/paths.cmake
cmake_modules/utils.cmake
hedgewars/CMakeLists.txt
hedgewars/GSHandlers.inc
hedgewars/SDLMain.h
hedgewars/SDLMain.m
hedgewars/SDLh.pas
hedgewars/avwrapper.c
hedgewars/avwrapper/CMakeLists.txt
hedgewars/avwrapper/avwrapper.c
hedgewars/uGears.pas
hedgewars/uPhysFSLayer.pas
hedgewars/uTeams.pas
misc/libphysfs/CMakeLists.txt
tools/build_windows.bat
--- a/CMakeLists.txt	Thu Jun 13 22:04:22 2013 +0200
+++ b/CMakeLists.txt	Thu Jun 13 22:27:23 2013 +0200
@@ -9,7 +9,7 @@
 endforeach()
 
 set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules")
-
+include(${CMAKE_MODULE_PATH}/utils.cmake)
 
 #possible cmake configuration
 option(NOSERVER "Disable gameServer build (off)]" OFF)
@@ -92,49 +92,35 @@
 endif()
 
 #parse additional parameters
-if(FPFLAGS OR GHFLAGS)
-    if(CMAKE_VERSION VERSION_GREATER "2.6")
-        separate_arguments(fpflags_parsed UNIX_COMMAND ${FPFLAGS})
+if(FPFLAGS)
+    add_flag_prepend(CMAKE_Pascal_FLAGS ${FPFLAGS})
+endif()
+if(GHFLAGS)
+    if(${allow_parse_args})
         separate_arguments(ghflags_parsed UNIX_COMMAND ${GHFLAGS})
     else()
-        message("*** FPFLAGS and GHFLAGS are available only when using CMake >= 2.8 ***")
+        message(${WARNING} "FPFLAGS and GHFLAGS are available only when using CMake >= 2.8")
     endif()
 endif()
 
-list(APPEND pascal_flags ${fpflags_parsed}            # user flags
-                 "-B"                                 # compile all units
-                 "-vm4079,4080,4081"                  # fpc verbosity output format
-                 "-FE${PROJECT_BINARY_DIR}/bin"       # fpc binaries output directory
-                 "-FU${PROJECT_BINARY_DIR}/hedgewars" # fpc units output directory
-                 "-Fl${PROJECT_BINARY_DIR}/bin"       # fpc linking directory (win/unix)
-                 "-Fi${PROJECT_BINARY_DIR}/hedgewars" # fpc .inc path (for out of source builds)
-                 "-k-L${PROJECT_BINARY_DIR}/bin"      # ld linking directory (unix/osx)
-                 "-Cs2000000"                         # stack size
-                 "-vewnq"                             # fpc output verbosity
-                 "-dDEBUGFILE"                        # macro for engine output
-                 )
+
 list(APPEND haskell_flags ${ghflags_parsed} # user flags
                  "-O2"                      # optimise for faster code
                  )
 
+#-vm4079,4080,4081
+add_flag_append(CMAKE_Pascal_FLAGS "-Cs2000000")
+add_flag_append(CMAKE_Pascal_FLAGS_DEBUG "-O- -gv")
+add_flag_append(CMAKE_Pascal_FLAGS_RELEASE "-Os -Xs")
 
 #get BUILD_TYPE and enable/disable optimisation
 message(STATUS "Using ${CMAKE_BUILD_TYPE} configuration")
 if(CMAKE_BUILD_TYPE MATCHES "DEBUG")
-    list(APPEND pascal_flags "-O-" # disable all optimisations
-                             "-g"  # enable debug symbols
-                             "-gl" # add line info to bt
-                             "-gv" # allow valgrind
-                             )
     list(APPEND haskell_flags "-Wall"       # all warnings
                               "-debug"      # debug mode
                               "-dcore-lint" # internal sanity check
                               )
 else()
-    list(APPEND pascal_flags "-Os" # optimise for size
-                             "-Xs" # strip binary
-                             "-Si" # turn on inlining
-                             )
     list(APPEND haskell_flags "-w" # no warnings
                               )
 endif()
@@ -192,10 +178,6 @@
     endif()
     set(physfs_output_name "hwphysfs")
     add_subdirectory(misc/libphysfs)
-    #-XLA is a beta fpc flag that renames libraries before passing them to the linker
-    #we also have to pass PHYSFS_INTERNAL to satisfy windows runtime requirements
-    #(should be harmless on other platforms)
-    list(APPEND pascal_flags "-XLAphysfs=${physfs_output_name}" "-dPHYSFS_INTERNAL")
 endif()
 
 find_package_or_disable_msg(FFMPEG NOVIDEOREC "Video recording will not be built")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake_modules/CMakeDeterminePascalCompiler.cmake	Thu Jun 13 22:27:23 2013 +0200
@@ -0,0 +1,65 @@
+# Determine the compiler to use for Pascal programs
+# NOTE, a generator may set CMAKE_Pascal_COMPILER before
+# loading this file to force a compiler.
+# use environment variable Pascal first if defined by user, next use
+# the cmake variable CMAKE_GENERATOR_PASCAL which can be defined by a generator
+# as a default compiler
+
+if(NOT CMAKE_Pascal_COMPILER)
+    # prefer the environment variable FPC
+    if($ENV{FPC} MATCHES ".+")
+        get_filename_component(CMAKE_Pascal_COMPILER_INIT $ENV{FPC} PROGRAM PROGRAM_ARGS CMAKE_Pascal_FLAGS_ENV_INIT)
+        if(CMAKE_Pascal_FLAGS_ENV_INIT)
+            set(CMAKE_Pascal_COMPILER_ARG1 "${CMAKE_Pascal_FLAGS_ENV_INIT}" CACHE STRING "First argument to Pascal compiler")
+        endif(CMAKE_Pascal_FLAGS_ENV_INIT)
+        if(EXISTS ${CMAKE_Pascal_COMPILER_INIT})
+        else(EXISTS ${CMAKE_Pascal_COMPILER_INIT})
+            message(FATAL_ERROR "Could not find compiler set in environment variable FPC:\n$ENV{FPC}.")
+        endif(EXISTS ${CMAKE_Pascal_COMPILER_INIT})
+    endif($ENV{FPC} MATCHES ".+")
+
+    # next try prefer the compiler specified by the generator
+    if(CMAKE_GENERATOR_PASCAL)
+        if(NOT CMAKE_Pascal_COMPILER_INIT)
+            set(CMAKE_Pascal_COMPILER_INIT ${CMAKE_GENERATOR_PASCAL})
+        endif(NOT CMAKE_Pascal_COMPILER_INIT)
+    endif(CMAKE_GENERATOR_PASCAL)
+
+    # finally list compilers to try
+    if(CMAKE_Pascal_COMPILER_INIT)
+        set(CMAKE_Pascal_COMPILER_LIST ${CMAKE_Pascal_COMPILER_INIT})
+    else(CMAKE_Pascal_COMPILER_INIT)
+        set(CMAKE_Pascal_COMPILER_LIST fpc)
+    endif(CMAKE_Pascal_COMPILER_INIT)
+
+    # Find the compiler.
+    find_program(CMAKE_Pascal_COMPILER NAMES ${CMAKE_Pascal_COMPILER_LIST} DOC "Pascal compiler")
+    if(CMAKE_Pascal_COMPILER_INIT AND NOT CMAKE_Pascal_COMPILER)
+        set(CMAKE_Pascal_COMPILER "${CMAKE_Pascal_COMPILER_INIT}" CACHE FILEPATH "Pascal compiler" FORCE)
+    endif(CMAKE_Pascal_COMPILER_INIT AND NOT CMAKE_Pascal_COMPILER)
+endif(NOT CMAKE_Pascal_COMPILER)
+mark_as_advanced(CMAKE_Pascal_COMPILER)
+
+if(NOT CMAKE_Pascal_COMPILER_VERSION)
+    execute_process(COMMAND ${CMAKE_Pascal_COMPILER} -iV
+                    OUTPUT_VARIABLE CMAKE_Pascal_COMPILER_VERSION
+                    OUTPUT_STRIP_TRAILING_WHITESPACE
+                    ) # we assume no error for something so simple
+endif(NOT CMAKE_Pascal_COMPILER_VERSION)
+mark_as_advanced(CMAKE_Pascal_COMPILER_VERSION)
+
+get_filename_component(COMPILER_LOCATION "${CMAKE_Pascal_COMPILER}" PATH)
+
+# configure variables set in this file for fast reload later on
+if(${CMAKE_VERSION} VERSION_LESS 2.8.10)
+    configure_file(${CMAKE_MODULE_PATH}/CMakePascalCompiler.cmake.in
+                   "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakePascalCompiler.cmake"
+                   IMMEDIATE )
+else(${CMAKE_VERSION} VERSION_LESS 2.8.10)
+    configure_file(${CMAKE_MODULE_PATH}/CMakePascalCompiler.cmake.in
+                  "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/${CMAKE_VERSION}/CMakePascalCompiler.cmake"
+                   IMMEDIATE )
+endif(${CMAKE_VERSION} VERSION_LESS 2.8.10)
+
+set(CMAKE_Pascal_COMPILER_ENV_VAR "FPC")
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake_modules/CMakePascalCompiler.cmake.in	Thu Jun 13 22:27:23 2013 +0200
@@ -0,0 +1,12 @@
+set(CMAKE_Pascal_COMPILER "@CMAKE_Pascal_COMPILER@")
+set(CMAKE_Pascal_COMPILER_ARG1 "@CMAKE_Pascal_COMPILER_ARG1@")
+set(CMAKE_Pascal_COMPILER_LOADED 1)
+set(CMAKE_Pascal_COMPILER_VERSION "@CMAKE_Pascal_COMPILER_VERSION@")
+
+set(CMAKE_Pascal_COMPILER_ENV_VAR "FPC")
+
+set(CMAKE_Pascal_SOURCE_FILE_EXTENSIONS "pas" "pp")
+set(CMAKE_Pascal_IGNORE_EXTENSIONS ppu;PPU;h;H;o;O;obj;OBJ;def;DEF;rc;RC)
+set(CMAKE_Pascal_LINKER_PREFERENCE Prefered)
+set(CMAKE_Pascal_OUTPUT_EXTENSION_REPLACE 1)
+set(CMAKE_Pascal_OUTPUT_EXTENSION ".o")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake_modules/CMakePascalInformation.cmake	Thu Jun 13 22:27:23 2013 +0200
@@ -0,0 +1,208 @@
+# This file sets the basic flags for the Pascal language in CMake.
+# It also loads the available platform file for the system-compiler
+# if it exists.
+
+get_filename_component(CMAKE_BASE_NAME ${CMAKE_Pascal_COMPILER} NAME_WE)
+set(CMAKE_SYSTEM_AND_Pascal_COMPILER_INFO_FILE
+    ${CMAKE_ROOT}/Modules/Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME}.cmake)
+include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL)
+
+# This section should actually be in Platform/${CMAKE_SYSTME_NAME}-fpc.cmake
+set(CMAKE_Pascal_FLAGS_INIT "-l- -v0ewn")
+set(CMAKE_Pascal_FLAGS_DEBUG_INIT "-g -gl -gp -gh")
+set(CMAKE_Pascal_FLAGS_MINSIZEREL_INIT "-Os -dNDEBUG")
+set(CMAKE_Pascal_FLAGS_RELEASE_INIT "-O3 -dNDEBUG")
+set(CMAKE_Pascal_FLAGS_RELWITHDEBINFO_INIT "-O2 -g -gl -gp")
+
+# This should be included before the _INIT variables are
+# used to initialize the cache. Since the rule variables
+# have if blocks on them, users can still define them here.
+# But, it should still be after the platform file so changes can
+# be made to those values.
+
+if(CMAKE_USER_MAKE_RULES_OVERRIDE)
+   include(${CMAKE_USER_MAKE_RULES_OVERRIDE})
+endif(CMAKE_USER_MAKE_RULES_OVERRIDE)
+
+if(CMAKE_USER_MAKE_RULES_OVERRIDE_Pascal)
+   include(${CMAKE_USER_MAKE_RULES_OVERRIDE_Pascal})
+endif(CMAKE_USER_MAKE_RULES_OVERRIDE_Pascal)
+
+# Create a set of shared library variable specific to Pascal
+# For 90% of the systems, these are the same flags as the C versions
+# so if these are not set just copy the flags from the c version
+
+# No flags supported during linking as a shell script takes care of it
+if(NOT CMAKE_SHARED_LIBRARY_CREATE_Pascal_FLAGS)
+#-dynamiclib -Wl,-headerpad_max_install_names for C
+    set(CMAKE_SHARED_LIBRARY_CREATE_Pascal_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS})
+endif(NOT CMAKE_SHARED_LIBRARY_CREATE_Pascal_FLAGS)
+
+if(NOT CMAKE_SHARED_LIBRARY_Pascal_FLAGS)
+    #another similarity, fpc: -fPIC  Same as -Cg
+    #(maybe required only for x86_64)
+    set(CMAKE_SHARED_LIBRARY_Pascal_FLAGS ${CMAKE_SHARED_LIBRARY_C_FLAGS})
+endif(NOT CMAKE_SHARED_LIBRARY_Pascal_FLAGS)
+
+if(NOT CMAKE_SHARED_LIBRARY_LINK_Pascal_FLAGS)
+    set(CMAKE_SHARED_LIBRARY_LINK_Pascal_FLAGS ${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS})
+endif(NOT CMAKE_SHARED_LIBRARY_LINK_Pascal_FLAGS)
+
+#if(NOT CMAKE_SHARED_LIBRARY_RUNTIME_Pascal_FLAG)
+#    set(CMAKE_SHARED_LIBRARY_RUNTIME_Pascal_FLAG ${CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG})
+#endif(NOT CMAKE_SHARED_LIBRARY_RUNTIME_Pascal_FLAG)
+
+#if(NOT CMAKE_SHARED_LIBRARY_RUNTIME_Pascal_FLAG_SEP)
+#    set(CMAKE_SHARED_LIBRARY_RUNTIME_Pascal_FLAG_SEP ${CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP})
+#endif(NOT CMAKE_SHARED_LIBRARY_RUNTIME_Pascal_FLAG_SEP)
+
+if(NOT CMAKE_SHARED_LIBRARY_RPATH_LINK_Pascal_FLAG)
+    set(CMAKE_SHARED_LIBRARY_RPATH_LINK_Pascal_FLAG ${CMAKE_SHARED_LIBRARY_RPATH_LINK_C_FLAG})
+endif(NOT CMAKE_SHARED_LIBRARY_RPATH_LINK_Pascal_FLAG)
+
+# for most systems a module is the same as a shared library
+# so unless the variable CMAKE_MODULE_EXISTS is set just
+# copy the values from the LIBRARY variables
+if(NOT CMAKE_MODULE_EXISTS)
+    set(CMAKE_SHARED_MODULE_Pascal_FLAGS ${CMAKE_SHARED_LIBRARY_Pascal_FLAGS})
+    set(CMAKE_SHARED_MODULE_CREATE_Pascal_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_Pascal_FLAGS})
+endif(NOT CMAKE_MODULE_EXISTS)
+
+# repeat for modules
+if(NOT CMAKE_SHARED_MODULE_CREATE_Pascal_FLAGS)
+    set(CMAKE_SHARED_MODULE_CREATE_Pascal_FLAGS ${CMAKE_SHARED_MODULE_CREATE_C_FLAGS})
+endif(NOT CMAKE_SHARED_MODULE_CREATE_Pascal_FLAGS)
+
+if(NOT CMAKE_SHARED_MODULE_Pascal_FLAGS)
+    set(CMAKE_SHARED_MODULE_Pascal_FLAGS ${CMAKE_SHARED_MODULE_C_FLAGS})
+endif(NOT CMAKE_SHARED_MODULE_Pascal_FLAGS)
+
+if(NOT CMAKE_SHARED_MODULE_RUNTIME_Pascal_FLAG)
+    set(CMAKE_SHARED_MODULE_RUNTIME_Pascal_FLAG ${CMAKE_SHARED_MODULE_RUNTIME_C_FLAG})
+endif(NOT CMAKE_SHARED_MODULE_RUNTIME_Pascal_FLAG)
+
+if(NOT CMAKE_SHARED_MODULE_RUNTIME_Pascal_FLAG_SEP)
+    set(CMAKE_SHARED_MODULE_RUNTIME_Pascal_FLAG_SEP ${CMAKE_SHARED_MODULE_RUNTIME_C_FLAG_SEP})
+endif(NOT CMAKE_SHARED_MODULE_RUNTIME_Pascal_FLAG_SEP)
+
+if(NOT CMAKE_INCLUDE_FLAG_Pascal)
+    #amazing, fpc: -I<x>  Add <x> to include path
+    set(CMAKE_INCLUDE_FLAG_Pascal ${CMAKE_INCLUDE_FLAG_C})
+endif(NOT CMAKE_INCLUDE_FLAG_Pascal)
+
+if(NOT CMAKE_INCLUDE_FLAG_SEP_Pascal)
+    set(CMAKE_INCLUDE_FLAG_SEP_Pascal ${CMAKE_INCLUDE_FLAG_SEP_C})
+endif(NOT CMAKE_INCLUDE_FLAG_SEP_Pascal)
+
+# Copy C version of this flag which is normally determined in platform file.
+if(NOT CMAKE_SHARED_LIBRARY_SONAME_Pascal_FLAG)
+    set(CMAKE_SHARED_LIBRARY_SONAME_Pascal_FLAG ${CMAKE_SHARED_LIBRARY_SONAME_C_FLAG})
+endif(NOT CMAKE_SHARED_LIBRARY_SONAME_Pascal_FLAG)
+
+set(CMAKE_VERBOSE_MAKEFILE FALSE CACHE BOOL "If this value is on, makefiles will be generated without the .SILENT directive, and all commands will be echoed to the console during the make.  This is useful for debugging only. With Visual Studio IDE projects all commands are done without /nologo.")
+
+set(CMAKE_Pascal_FLAGS "$ENV{FPFLAGS} ${CMAKE_Pascal_FLAGS_INIT}" CACHE STRING "Flags for Pascal compiler.")
+
+include(CMakeCommonLanguageInclude)
+
+# now define the following rule variables
+
+# CMAKE_Pascal_CREATE_SHARED_LIBRARY
+# CMAKE_Pascal_CREATE_SHARED_MODULE
+# CMAKE_Pascal_CREATE_STATIC_LIBRARY
+# CMAKE_Pascal_COMPILE_OBJECT
+# CMAKE_Pascal_LINK_EXECUTABLE
+
+# variables supplied by the generator at use time
+# <TARGET>
+# <TARGET_BASE> the target without the suffix
+# <OBJECTS>
+# <OBJECT>
+# <LINK_LIBRARIES>
+# <FLAGS>
+# <LINK_FLAGS>
+
+# Pascal compiler information
+# <CMAKE_Pascal_COMPILER>
+# <CMAKE_SHARED_LIBRARY_CREATE_Pascal_FLAGS>
+# <CMAKE_SHARED_MODULE_CREATE_Pascal_FLAGS>
+# <CMAKE_Pascal_LINK_FLAGS>
+
+# Static library tools
+#  NONE!
+
+if(NOT EXECUTABLE_OUTPUT_PATH)
+    set (EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR})
+endif(NOT EXECUTABLE_OUTPUT_PATH)
+
+# create a Pascal shared library
+if(NOT CMAKE_Pascal_CREATE_SHARED_LIBRARY)
+    if(WIN32)
+        set(CMAKE_Pascal_CREATE_SHARED_LIBRARY "${EXECUTABLE_OUTPUT_PATH}/ppas.bat")
+    else(WIN32)
+        set(CMAKE_Pascal_CREATE_SHARED_LIBRARY "${EXECUTABLE_OUTPUT_PATH}/ppas.sh")
+    endif(WIN32)
+# other expandable variables here are <CMAKE_Pascal_COMPILER> <CMAKE_SHARED_LIBRARY_Pascal_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_Pascal_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_Pascal_FLAG> <TARGET_SONAME> <TARGET> <OBJECTS> <LINK_LIBRARIES>
+endif(NOT CMAKE_Pascal_CREATE_SHARED_LIBRARY)
+
+# create an Pascal shared module just copy the shared library rule
+if(NOT CMAKE_Pascal_CREATE_SHARED_MODULE)
+  set(CMAKE_Pascal_CREATE_SHARED_MODULE ${CMAKE_Pascal_CREATE_SHARED_LIBRARY})
+endif(NOT CMAKE_Pascal_CREATE_SHARED_MODULE)
+
+# create an Pascal static library (unsupported)
+if(NOT CMAKE_Pascal_CREATE_STATIC_LIBRARY)
+  set(CMAKE_Pascal_CREATE_STATIC_LIBRARY
+      "echo STATIC LIBRARIES ARE NOT SUPPORTED" "exit")
+endif(NOT CMAKE_Pascal_CREATE_STATIC_LIBRARY)
+
+# compile a Pascal file into an object file
+if(NOT CMAKE_Pascal_COMPILE_OBJECT)
+    if(UNIX)
+        #when you have multiple ld installation make sure you get the one bundled with the system C compiler
+        include(Platform/${CMAKE_SYSTEM_NAME}-GNU-C.cmake OPTIONAL)
+        if(CMAKE_C_COMPILER)
+            get_filename_component(CMAKE_C_COMPILER_DIR ${CMAKE_C_COMPILER} PATH)
+            set(CMAKE_Pascal_UNIX_FLAGS "-FD${CMAKE_C_COMPILER_DIR}")
+        endif(CMAKE_C_COMPILER)
+        if(APPLE)
+            #add user framework directory
+            set(CMAKE_Pascal_UNIX_FLAGS "-Ff~/Library/Frameworks ${CMAKE_Pascal_UNIX_FLAGS}")
+        endif(APPLE)
+    endif(UNIX)
+
+    set(CMAKE_Pascal_COMPILE_OBJECT
+        "<CMAKE_Pascal_COMPILER> -Cn -FE${EXECUTABLE_OUTPUT_PATH} -FU${CMAKE_CURRENT_BINARY_DIR}/<OBJECT_DIR> ${CMAKE_Pascal_UNIX_FLAGS} <FLAGS> <SOURCE>")
+endif(NOT CMAKE_Pascal_COMPILE_OBJECT)
+
+# link Pascal objects in a single executable
+if(NOT CMAKE_Pascal_LINK_EXECUTABLE)
+    if(WIN32)
+        set(CMAKE_Pascal_LINK_EXECUTABLE "${EXECUTABLE_OUTPUT_PATH}/ppas.bat")
+    else(WIN32)
+        set(CMAKE_Pascal_LINK_EXECUTABLE "${EXECUTABLE_OUTPUT_PATH}/ppas.sh")
+    endif(WIN32)
+# other expandable variables here are <CMAKE_Pascal_LINK_FLAGS> <LINK_FLAGS> <TARGET_BASE> <FLAGS> <LINK_LIBRARIES>
+endif(NOT CMAKE_Pascal_LINK_EXECUTABLE)
+
+if(CMAKE_Pascal_STANDARD_LIBRARIES_INIT)
+    set(CMAKE_Pascal_STANDARD_LIBRARIES "${CMAKE_Pascal_STANDARD_LIBRARIES_INIT}"
+    CACHE STRING "Libraries linked by default (usually handled internally).")
+    mark_as_advanced(CMAKE_Pascal_STANDARD_LIBRARIES)
+endif(CMAKE_Pascal_STANDARD_LIBRARIES_INIT)
+
+if(NOT CMAKE_NOT_USING_CONFIG_FLAGS)
+    set(CMAKE_Pascal_FLAGS_DEBUG "${CMAKE_Pascal_FLAGS_DEBUG_INIT}" CACHE STRING
+        "Flags used by the compiler during debug builds.")
+    set(CMAKE_Pascal_FLAGS_MINSIZEREL "${CMAKE_Pascal_FLAGS_MINSIZEREL_INIT}" CACHE STRING
+        "Flags used by the compiler during release minsize builds.")
+    set(CMAKE_Pascal_FLAGS_RELEASE "${CMAKE_Pascal_FLAGS_RELEASE_INIT}" CACHE STRING
+        "Flags used by the compiler during release builds (/MD /Ob1 /Oi /Ot /Oy /Gs will produce slightly less optimized but smaller files).")
+    set(CMAKE_Pascal_FLAGS_RELWITHDEBINFO "${CMAKE_Pascal_FLAGS_RELWITHDEBINFO_INIT}" CACHE STRING
+        "Flags used by the compiler during Release with Debug Info builds.")
+endif(NOT CMAKE_NOT_USING_CONFIG_FLAGS)
+
+mark_as_advanced(CMAKE_Pascal_FLAGS CMAKE_Pascal_FLAGS_DEBUG CMAKE_Pascal_FLAGS_MINSIZEREL
+                 CMAKE_Pascal_FLAGS_RELEASE CMAKE_Pascal_FLAGS_RELWITHDEBINFO)
+set(CMAKE_Pascal_INFORMATION_LOADED 1)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake_modules/CMakeTestPascalCompiler.cmake	Thu Jun 13 22:27:23 2013 +0200
@@ -0,0 +1,53 @@
+# This file is used by EnableLanguage in cmGlobalGenerator to determine that
+# the FreePascal can actually compile and link the most basic of programs.
+# If not, a fatal error is set, cmake stops processing commands and will not
+# generate any makefiles or projects.
+
+if(NOT CMAKE_Pascal_COMPILER_WORKS)
+    message(STATUS "Check for working Pascal compiler: ${CMAKE_Pascal_COMPILER}")
+    file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeTmp/testpascalcompiler.pas
+         "program testPascalCompiler;
+          begin
+          end.
+         ")
+
+    file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeTmp/CMakeLists.txt
+         "set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake_modules)
+          set(CMAKE_VERBOSE_MAKEFILE ON CACHE BOOL \"\" FORCE)
+          project(test Pascal)
+          add_executable(testpascalcompiler testpascalcompiler.pas)
+         ")
+
+# To avoid try_compile recurse error, use any binary directory other
+# than ${CMAKE_BINARY_DIR}. The choice of
+# bindir = ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp is
+# especially advantageous since it makes an in-source build which
+# means that no special variables need to be set to find files.
+    try_compile(CMAKE_Pascal_COMPILER_WORKS
+                ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeTmp
+                ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeTmp
+                test
+                OUTPUT_VARIABLE RESULT_OUTPUT
+                )
+    set(PASCAL_TEST_WAS_RUN 1)
+endif(NOT CMAKE_Pascal_COMPILER_WORKS)
+
+if(NOT CMAKE_Pascal_COMPILER_WORKS)
+    message(STATUS "Check for working Pascal compiler: ${CMAKE_Pascal_COMPILER} -- broken")
+    file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeError.log
+         "Determining if the Pascal compiler works failed with "
+         "the following output:\n${RESULT_OUTPUT}\n\n")
+    message(FATAL_ERROR "The Pascal builder \"${CMAKE_Pascal_COMPILER}\" "
+            "is not able to compile and link a simple test program.\nIt fails "
+            "with the following output:\n ${RESULT_OUTPUT}\n\n"
+            "CMake will not be able to correctly generate this project.")
+else(NOT CMAKE_Pascal_COMPILER_WORKS)
+    if(PASCAL_TEST_WAS_RUN)
+        message(STATUS "Check for working Pascal compiler: ${CMAKE_Pascal_COMPILER} -- works")
+        file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+             "Determining if the Pascal compiler works passed with "
+             "the following output:\n${RESULT_OUTPUT}\n\n")
+    endif(PASCAL_TEST_WAS_RUN)
+    set(CMAKE_Pascal_COMPILER_WORKS 1 CACHE INTERNAL "")
+endif(NOT CMAKE_Pascal_COMPILER_WORKS)
+
--- a/cmake_modules/FindFreePascal.cmake	Thu Jun 13 22:04:22 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-# - Try to find the FreePascal executable
-# Once done this will define
-#
-#  FREEPASCAL_FOUND       - system has Freepascal
-#  FREEPASCAL_VERSION     - Freepascal version
-#  FREEPASCAL_EXECUTABLE  - Freepascal executable
-#
-# Copyright (c) 2012, Bryan Dunsmore <dunsmoreb@gmail.com>
-# Copyright (c) 2013, Vittorio Giovara <vittorio.giovara@gmail.com>
-#
-# Redistribution and use is allowed according to the terms of the BSD license.
-# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
-
-
-find_program(FREEPASCAL_EXECUTABLE
-    NAMES fpc
-    PATHS /opt/local/bin /usr/local/bin /usr/bin
-    )
-
-if (FREEPASCAL_EXECUTABLE)
-    # check Freepascal version
-    execute_process(COMMAND ${FREEPASCAL_EXECUTABLE} -iV
-                    OUTPUT_VARIABLE FREEPASCAL_VERSION
-                    ERROR_VARIABLE FREEPASCAL_VERSION_ERROR
-                    RESULT_VARIABLE FREEPASCAL_VERSION_RESULT
-                    OUTPUT_STRIP_TRAILING_WHITESPACE
-                    )
-
-    if(NOT ${FREEPASCAL_VERSION_RESULT} EQUAL 0)
-        message(SEND_ERROR "Command \"${FREEPASCAL_EXECUTABLE} -iV\" failed with output: ${FREEPASCAL_VERSION_ERROR}")
-    endif()
-endif()
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(FreePascal DEFAULT_MSG FREEPASCAL_EXECUTABLE FREEPASCAL_VERSION)
-mark_as_advanced(FREEPASCAL_VERSION)
-
--- a/cmake_modules/paths.cmake	Thu Jun 13 22:04:22 2013 +0200
+++ b/cmake_modules/paths.cmake	Thu Jun 13 22:27:23 2013 +0200
@@ -1,6 +1,16 @@
 #where to build libs and bins
 set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
 set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
+#these variables are for non-makefile generators
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH})
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH})
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${LIBRARY_OUTPUT_PATH})
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${LIBRARY_OUTPUT_PATH})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${LIBRARY_OUTPUT_PATH})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${LIBRARY_OUTPUT_PATH})
 
 #resource paths
 if(UNIX AND NOT APPLE)
--- a/cmake_modules/utils.cmake	Thu Jun 13 22:04:22 2013 +0200
+++ b/cmake_modules/utils.cmake	Thu Jun 13 22:27:23 2013 +0200
@@ -35,3 +35,12 @@
 
 #TODO: find_package_or_bundle
 
+
+macro(add_flag_append _VAR_NAME _FLAG)
+    set(${_VAR_NAME} "${${_VAR_NAME}} ${_FLAG}")
+endmacro(add_flag_append _VAR_NAME _FLAG)
+
+macro(add_flag_prepend _VAR_NAME _FLAG)
+    set(${_VAR_NAME} "${_FLAG} ${${_VAR_NAME}}")
+endmacro(add_flag_prepend _VAR_NAME _FLAG)
+
--- a/hedgewars/CMakeLists.txt	Thu Jun 13 22:04:22 2013 +0200
+++ b/hedgewars/CMakeLists.txt	Thu Jun 13 22:27:23 2013 +0200
@@ -5,166 +5,143 @@
 find_package(SDL_mixer)
 
 include (CheckLibraryExists)
-#Mix_Init/Mix_Quit from SDL_mixer 1.2.10
-check_library_exists(${SDLMIXER_LIBRARY} Mix_Init "" HAVE_MIXINIT)
-if(HAVE_MIXINIT)
-    list(APPEND pascal_flags "-dSDL_MIXER_NEWER")
-endif()
-#IMG_Init/IMG_Quit from SDL_image 1.2.8
-check_library_exists(${SDLIMAGE_LIBRARY} IMG_Init "" HAVE_IMGINIT)
-if(HAVE_IMGINIT)
-    list(APPEND pascal_flags "-dSDL_IMAGE_NEWER")
-endif()
+
+
+enable_language(Pascal)
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.inc.in ${CMAKE_CURRENT_BINARY_DIR}/config.inc)
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.inc.in ${CMAKE_CURRENT_BINARY_DIR}/config.inc)
-
-#SOURCE AND PROGRAMS SECTION
-if(${BUILD_ENGINE_LIBRARY})
-    set(engine_output_name "${CMAKE_SHARED_LIBRARY_PREFIX}hwengine${CMAKE_SHARED_LIBRARY_SUFFIX}")
-    set(hwengine_project hwLibrary.pas)
-else()
-    set(engine_output_name "hwengine${CMAKE_EXECUTABLE_SUFFIX}")
-    set(hwengine_project hwengine.pas)
-endif()
-
-if (APPLE)
-    set(required_fpc_version 2.6)
-else()
-    set(required_fpc_version 2.2)
-endif()
-
 set(engine_sources
-    ${hwengine_project}
+    SDLh.pas
+    uSinTable.pas
+    uFloat.pas
+    uConsts.pas
     LuaPas.pas
     PNGh.pas
-    SDLh.pas
-    uAI.pas
-    uAIActions.pas
+    uTypes.pas
+    uUtils.pas
+    uVariables.pas
+    uMisc.pas
+    uConsole.pas
+    uDebug.pas
+    uCommands.pas
+    uInputHandler.pas
+    uTextures.pas
+    uRenderUtils.pas
+    uRender.pas
+    uCaptions.pas
+    uLandTexture.pas
+    uIO.pas
+    uChat.pas
+    uPhysFSLayer.pas
+    uStore.pas
+    uSound.pas
+    uRandom.pas
+    uLocale.pas
+    uStats.pas
+    uCursor.pas
+    uVideoRec.pas
     uAILandMarks.pas
-    uAIAmmoTests.pas
-    uAIMisc.pas
+    adler32.pas
+    uLandTemplates.pas
+    uLandGraphics.pas
+    uLandPainted.pas
+    uLandOutline.pas
+    uLandGenMaze.pas
+    uLandObjects.pas
+    uLand.pas
     uAmmos.pas
-    uCaptions.pas
-    uChat.pas
+
+    uAIMisc.pas
+    uAIActions.pas
+    uAI.pas
+    uWorld.pas
+    uVisualGears.pas
+    uTeams.pas
+
+    uGearsList.pas
     uCollisions.pas
-    uCommands.pas
+    uAIAmmoTests.pas
+    uGears.pas
+    uGame.pas
     uCommandHandlers.pas
-    uConsole.pas
-    uConsts.pas
-    uCursor.pas
-    uDebug.pas
-    uFloat.pas
-    uGame.pas
-    uGears.pas
     uGearsHandlers.pas
     uGearsHandlersRope.pas
     uGearsHedgehog.pas
-    uGearsList.pas
     uGearsRender.pas
     uGearsUtils.pas
-    uIO.pas
-    uInputHandler.pas
-    uLand.pas
-    uLandGenMaze.pas
-    uLandGraphics.pas
-    uLandObjects.pas
-    uLandOutline.pas
-    uLandPainted.pas
-    uLandTemplates.pas
-    uLandTexture.pas
-    uLocale.pas
-    uMisc.pas
-    uPhysFSLayer.pas
-    uRandom.pas
-    uRender.pas
-    uRenderUtils.pas
     uScript.pas
-    uSinTable.pas
-    uSound.pas
-    uStats.pas
-    uStore.pas
-    uTeams.pas
-    uTextures.pas
-    uTouch.pas
-    uTypes.pas
-    uUtils.pas
-    uVariables.pas
-    uVideoRec.pas
-    uVisualGears.pas
-    uWorld.pas
+    hwengine.pas
+
     GSHandlers.inc
     VGSHandlers.inc
     ArgParsers.inc
     options.inc
-    adler32.pas
     ${CMAKE_CURRENT_BINARY_DIR}/config.inc
     )
 
 if(${BUILD_ENGINE_LIBRARY})
     message("*** Engine will be built as library (experimental) ***")
     list(APPEND pascal_flags "-dHWLIBRARY")
-
-    # create position independent code, only required for x68_64 builds, similar to -fPIC
-    if(CMAKE_SIZEOF_VOID_P MATCHES "8")
-        list(APPEND pascal_flags "-Cg")
-    endif(CMAKE_SIZEOF_VOID_P MATCHES "8")
-
-    # due to compiler/linker issues on Max OS X 10.6 -k-no_order_inits is needed to avoid linking fail
-    if(APPLE AND current_macosx_version VERSION_GREATER "10.5")
-        list(APPEND pascal_flags "-k-no_order_inits")
-    endif()
-    set(destination_dir ${target_library_install_dir})
-else(${BUILD_ENGINE_LIBRARY})
-    set(destination_dir ${target_binary_install_dir})
-endif(${BUILD_ENGINE_LIBRARY})
-
+endif()
 
 include(${CMAKE_MODULE_PATH}/utils.cmake)
 
-find_package_or_fail(FreePascal)
-
-#when cmake-2.6 support is dropped, this ought to be inside FindFreePascal.cmake
-if (FREEPASCAL_VERSION VERSION_LESS required_fpc_version)
-    message(FATAL_ERROR "Freepascal ${FREEPASCAL_VERSION} is too old, minimum version required is ${required_fpc_version}")
+if (${CMAKE_Pascal_COMPILER_VERSION} VERSION_LESS 2.2 OR # older versions are just ancient
+    (${CMAKE_Pascal_COMPILER_VERSION} VERSION_LESS 2.6 AND APPLE)) # because of 64bit and opengl bindings
+    message(FATAL_ERROR "Your FreePascal installation is too old (fpc ${CMAKE_Pascal_COMPILER_VERSION})!")
+elseif(CMAKE_Pascal_COMPILER_VERSION VERSION_GREATER 2.4)
+    #enable INLINE only with a recent version of fpc
+    add_flag_prepend(CMAKE_Pascal_FLAGS_RELEASE -Si)
 endif()
 
 
 #DEPENDECIES AND EXECUTABLES SECTION
 if(APPLE)
-    string(REGEX MATCH "[pP][pP][cC]+" powerpc_build "${CMAKE_OSX_ARCHITECTURES}")
-    string(REGEX MATCH "[iI]386+" i386_build "${CMAKE_OSX_ARCHITECTURES}")
-    string(REGEX MATCH "[xX]86_64+" x86_64_build "${CMAKE_OSX_ARCHITECTURES}")
-
-    if(powerpc_build)
-        set(powerpc_build "powerpc")
+    if(CMAKE_OSX_ARCHITECTURES)
+        #parse this system variable and adjust only the powerpc syntax to be compatible with -P
+        string(REGEX MATCH "[pP][pP][cC]+" powerpc_build "${CMAKE_OSX_ARCHITECTURES}")
+        string(REGEX MATCH "[iI]386+" i386_build "${CMAKE_OSX_ARCHITECTURES}")
+        string(REGEX MATCH "[xX]86_64+" x86_64_build "${CMAKE_OSX_ARCHITECTURES}")
+        if(x86_64_build)
+            add_flag_prepend(CMAKE_Pascal_FLAGS -Px86_64)
+        elseif(i386_build)
+            add_flag_prepend(CMAKE_Pascal_FLAGS -Pi386)
+        elseif(powerpc_build)
+            add_flag_prepend(CMAKE_Pascal_FLAGS -Ppowerpc)
+        else()
+            message(FATAL_ERROR "Unknown architecture present in CMAKE_OSX_ARCHITECTURES (${CMAKE_OSX_ARCHITECTURES})")
+        endif()
+        list(LENGTH CMAKE_OSX_ARCHITECTURES num_of_archs)
+        if(num_of_archs GREATER 1)
+            message(${WARNING} "Only one architecture in CMAKE_OSX_ARCHITECTURES is currently supported, picking the first one")
+        endif()
+    elseif(CMAKE_SIZEOF_VOID_P MATCHES "8")
+        #if that variable is not set check if we are on x86_64 and if so force it, else use default
+        add_flag_prepend(CMAKE_Pascal_FLAGS -Px86_64)
     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 BUILD_ENGINE_LIBRARY)
+        add_subdirectory(sdlmain)
+        list(APPEND HW_LINK_LIBS SDLmain)
+        add_flag_append(CMAKE_Pascal_FLAGS -Fl${LIBRARY_OUTPUT_PATH})
     endif()
 
-    #when you have multiple ld installation make sure you get the one bundled with the compiler
-    get_filename_component(compiler_dir ${CMAKE_C_COMPILER} PATH)
-    list(APPEND pascal_flags "-FD${compiler_dir}")
+    #when sysroot is set, make sure that fpc picks it
+    if(CMAKE_OSX_SYSROOT)
+        set(add_flag_append "-XD${CMAKE_OSX_SYSROOT}")
+    endif(CMAKE_OSX_SYSROOT)
 endif(APPLE)
 
+if(FFMPEG_FOUND)
+    add_subdirectory(avwrapper)
+    list(APPEND HW_LINK_LIBS avwrapper)
+    add_definitions(-dUSE_VIDEO_RECORDING)
+    add_flag_append(CMAKE_Pascal_FLAGS -Fl${LIBRARY_OUTPUT_PATH})
+endif()
+
 find_package_or_disable_msg(PNG NOPNG "Screenshots will be saved in BMP")
 if(PNG_FOUND)
     list(REMOVE_AT PNG_LIBRARIES 1) #removing the zlib library path
@@ -183,94 +160,55 @@
                              "-XLAlua=${LUA_LIBRARY_NAME}")
 endif()
 
-#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")
-    #under some configurations CMAKE_BUILD_TOOL fails to pass on the jobserver, breaking parallel compilation
-    if(UNIX)
-        set(SAFE_BUILD_TOOL $(MAKE))
-    else()
-        set(SAFE_BUILD_TOOL ${CMAKE_BUILD_TOOL})
-    endif()
-    add_custom_target(ENGINECLEAN COMMAND ${SAFE_BUILD_TOOL} "clean" "${PROJECT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}")
+
+if(NOT PHYSFS_FOUND)
+    add_definitions(-dPHYSFS_INTERNAL)
+    list(APPEND HW_LINK_LIBS physfs)
+    #-XLA is a beta fpc flag that renames libraries before passing them to the linker
+    #we also have to pass PHYSFS_INTERNAL to satisfy windows runtime requirements
+    #(should be harmless on other platforms)
+    add_flag_append(CMAKE_Pascal_FLAGS "-XLAphysfs=${physfs_output_name}")
 endif()
+list(APPEND HW_LINK_LIBS physlayer)
 
+#Mix_Init/Mix_Quit from SDL_mixer 1.2.10
+check_library_exists(${SDLMIXER_LIBRARY} Mix_Init "" HAVE_MIXINIT)
+if(HAVE_MIXINIT)
+    add_definitions(-dSDL_MIXER_NEWER)
+endif(HAVE_MIXINIT)
+
+#IMG_Init/IMG_Quit from SDL_image 1.2.8
+check_library_exists(${SDLIMAGE_LIBRARY} IMG_Init "" HAVE_IMGINIT)
+if(HAVE_IMGINIT)
+    add_definitions(-dSDL_IMAGE_NEWER)
+endif(HAVE_IMGINIT)
 
-if(${FFMPEG_FOUND})
-    list(APPEND pascal_flags "-dUSE_VIDEO_RECORDING")
+#needs to be last
+add_definitions(-dDEBUGFILE)
 
-    # TODO: this check is only for SDL < 2
-    # fpc will take care of linking but we need to have this library installed
-    find_package(GLUT REQUIRED)
+#SOURCE AND PROGRAMS SECTION
+if(BUILD_ENGINE_LIBRARY)
+    message(${WARNING} "Engine will be built as library (experimental)")
+    if(APPLE AND current_macosx_version VERSION_GREATER "10.5")
+        # due to compiler/linker issues on Max OS X 10.6 -k-no_order_inits is needed to avoid linking fail
+        add_flag_prepend(CMAKE_Pascal_FLAGS "-k-no_order_inits")
+    endif()
 
-    include_directories(${FFMPEG_INCLUDE_DIR})
-    add_library(avwrapper avwrapper.c)
-    #TODO: find good VERSION and SOVERSION values
-    target_link_libraries(avwrapper ${FFMPEG_LIBRARIES})
-    install(TARGETS avwrapper RUNTIME DESTINATION ${target_binary_install_dir}
-                              LIBRARY DESTINATION ${target_library_install_dir}
-                              ARCHIVE DESTINATION ${target_library_install_dir})
+    #workaround for missing <TARGET> support during object generation
+    set(engine_output_name "${CMAKE_SHARED_LIBRARY_PREFIX}hwengine${CMAKE_SHARED_LIBRARY_SUFFIX}")
+    set(destination_dir ${target_library_install_dir})
+    add_flag_prepend(CMAKE_Pascal_FLAGS "-o${LIBRARY_OUTPUT_PATH}/${engine_output_name}")
+
+    add_definitions(-dHWLIBRARY)
+    add_library(hwengine SHARED ${engine_sources} hwLibrary.pas)
+else()
+    # no need to change name here because target has same name
+    set(engine_output_name "hwengine${CMAKE_EXECUTABLE_SUFFIX}")
+    set(destination_dir ${target_binary_install_dir})
+    add_executable(hwengine ${engine_sources})
 endif()
 
-
-set(fpc_flags ${pascal_flags} ${hwengine_project})
-
-if(NOT APPLE)
-    #here is the command for standard executables or for shared library
-    add_custom_command(OUTPUT "${EXECUTABLE_OUTPUT_PATH}/${engine_output_name}"
-        COMMAND "${FREEPASCAL_EXECUTABLE}"
-        ARGS ${fpc_flags} -o${engine_output_name}
-        DEPENDS ${engine_sources}
-        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-        )
-else()
-    #these are the dependencies for building a universal binary on Mac OS X
-    foreach (build_arch ${powerpc_build} ${i386_build} ${x86_64_build})
-        list(APPEND lipo_args_list "${EXECUTABLE_OUTPUT_PATH}/hwengine.${build_arch}")
-        add_custom_command(OUTPUT "${EXECUTABLE_OUTPUT_PATH}/hwengine.${build_arch}"
-            COMMAND "${FREEPASCAL_EXECUTABLE}"
-            ARGS ${fpc_flags} -ohwengine.${build_arch} -P${build_arch}
-            DEPENDS ${engine_sources}
-            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-            )
-        add_custom_target(hwengine.${build_arch} ALL DEPENDS "${EXECUTABLE_OUTPUT_PATH}/hwengine.${build_arch}")
-        add_custom_command(TARGET hwengine.${build_arch} POST_BUILD
-            COMMAND "install_name_tool"
-            ARGS -id @executable_path/../Frameworks/${engine_output_name}
-                ${EXECUTABLE_OUTPUT_PATH}/hwengine.${build_arch}
-            )
-    endforeach()
-
-    add_custom_command(OUTPUT "${EXECUTABLE_OUTPUT_PATH}/${engine_output_name}"
-        COMMAND "lipo"
-        ARGS ${lipo_args_list} -create -output ${EXECUTABLE_OUTPUT_PATH}/${engine_output_name}
-        DEPENDS ${lipo_args_list}
-        )
-endif()
-
-
-add_custom_target(hwengine ALL DEPENDS "${EXECUTABLE_OUTPUT_PATH}/${engine_output_name}")
-
-#when system Lua is not found we need to compile it before engine
-if(NOT LUA_FOUND)
-    add_dependencies(hwengine lua)
-endif()
-
-# same for physfs
-if(NOT PHYSFS_FOUND)
-    add_dependencies(hwengine physfs)
-endif()
-
-add_dependencies(hwengine physlayer)
-
-#when ffmpeg/libav is found we need to compile it before engine
-#TODO: convert avwrapper to .pas unit so we can skip this step
-if(${FFMPEG_FOUND})
-    add_dependencies(hwengine avwrapper)
-endif()
-
-#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)
-endif()
+#even though not actually used, this will trigger relink if any lib changes
+target_link_libraries(hwengine ${HW_LINK_LIBS})
 
 install(PROGRAMS "${EXECUTABLE_OUTPUT_PATH}/${engine_output_name}" DESTINATION ${destination_dir})
--- a/hedgewars/GSHandlers.inc	Thu Jun 13 22:04:22 2013 +0200
+++ b/hedgewars/GSHandlers.inc	Thu Jun 13 22:27:23 2013 +0200
@@ -132,17 +132,6 @@
     HH^.Gear:= nil
 end;
 
-procedure RestoreHog(HH: PHedgehog);
-begin
-    HH^.Gear:=HH^.GearHidden;
-    HH^.GearHidden:= nil;
-    InsertGearToList(HH^.Gear);
-    HH^.Gear^.State:= (HH^.Gear^.State and (not (gstHHDriven or gstInvisible or gstAttacking))) or gstAttacked;
-    AddGearCI(HH^.Gear);
-    HH^.Gear^.Active:= true;
-    ScriptCall('onHogRestore', HH^.Gear^.Uid)
-end;
-
 
 ////////////////////////////////////////////////////////////////////////////////
 procedure doStepDrowningGear(Gear: PGear);
--- a/hedgewars/SDLMain.h	Thu Jun 13 22:04:22 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	Thu Jun 13 22:04:22 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	Thu Jun 13 22:04:22 2013 +0200
+++ b/hedgewars/SDLh.pas	Thu Jun 13 22:27:23 2013 +0200
@@ -54,7 +54,8 @@
 {$ENDIF}
 
 {$IFDEF DARWIN}
-    {$IFNDEF IPHONEOS}
+    {$IFNDEF HWLIBRARY}
+        {$linklib SDLmain}
         {$PASCALMAINNAME SDL_main}
         {$linkframework Cocoa}
         {$linkframework SDL}
@@ -76,19 +77,11 @@
     SDL_ImageLibName = 'SDL_image.dll';
     SDL_NetLibName = 'SDL_net.dll';
 {$ELSE}
-    {$IFDEF DARWIN}
-    SDLLibName = 'SDL';
-    SDL_TTFLibName = 'SDL_ttf';
-    SDL_MixerLibName = 'SDL_mixer';
-    SDL_ImageLibName = 'SDL_image';
-    SDL_NetLibName = 'SDL_net';
-    {$ELSE}
-    SDLLibName = 'libSDL.so';
-    SDL_TTFLibName = 'libSDL_ttf.so';
-    SDL_MixerLibName = 'libSDL_mixer.so';
-    SDL_ImageLibName = 'libSDL_image.so';
-    SDL_NetLibName = 'libSDL_net.so';
-    {$ENDIF}
+    SDLLibName = 'libSDL';
+    SDL_TTFLibName = 'libSDL_ttf';
+    SDL_MixerLibName = 'libSDL_mixer';
+    SDL_ImageLibName = 'libSDL_image';
+    SDL_NetLibName = 'libSDL_net';
 {$ENDIF}
 
 /////////////////////////////////////////////////////////////////
--- a/hedgewars/avwrapper.c	Thu Jun 13 22:04:22 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,517 +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
-
-#if (defined _MSC_VER)
-#define AVWRAP_DECL __declspec(dllexport)
-#elif ((__GNUC__ >= 3) && (!__EMX__) && (!sun))
-#define AVWRAP_DECL __attribute__((visibility("default")))
-#else
-#define AVWRAP_DECL
-#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;
-    }
-}
-
-AVWRAP_DECL 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);
-}
-
-AVWRAP_DECL 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;
-}
-
-AVWRAP_DECL 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);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/avwrapper/CMakeLists.txt	Thu Jun 13 22:27:23 2013 +0200
@@ -0,0 +1,15 @@
+#FFMPEG/Libav libraries have been searched already in main CMakeLists.txt
+
+# TODO: this check is only for SDL < 2
+# fpc will take care of linking but we need to have this library installed
+find_package(GLUT REQUIRED)
+
+include_directories(${FFMPEG_INCLUDE_DIR})
+
+add_library(avwrapper avwrapper.c)
+#TODO: find good VERSION and SOVERSION values
+target_link_libraries(avwrapper ${FFMPEG_LIBRARIES})
+install(TARGETS avwrapper RUNTIME DESTINATION ${target_binary_install_dir}
+                          LIBRARY DESTINATION ${target_library_install_dir}
+                          ARCHIVE DESTINATION ${target_library_install_dir})
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/avwrapper/avwrapper.c	Thu Jun 13 22:27:23 2013 +0200
@@ -0,0 +1,517 @@
+/*
+ * 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
+
+#if (defined _MSC_VER)
+#define AVWRAP_DECL __declspec(dllexport)
+#elif ((__GNUC__ >= 3) && (!__EMX__) && (!sun))
+#define AVWRAP_DECL __attribute__((visibility("default")))
+#else
+#define AVWRAP_DECL
+#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;
+    }
+}
+
+AVWRAP_DECL 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);
+}
+
+AVWRAP_DECL 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;
+}
+
+AVWRAP_DECL 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);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/sdlmain/CMakeLists.txt	Thu Jun 13 22:27:23 2013 +0200
@@ -0,0 +1,7 @@
+find_package(SDL REQUIRED)
+
+include_directories(${SDL_INCLUDE_DIR})
+
+add_library (SDLmain STATIC SDLMain.m)
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/sdlmain/SDLMain.h	Thu Jun 13 22:27:23 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/SDLMain.m	Thu Jun 13 22:27:23 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/uGears.pas	Thu Jun 13 22:04:22 2013 +0200
+++ b/hedgewars/uGears.pas	Thu Jun 13 22:27:23 2013 +0200
@@ -42,7 +42,6 @@
 function  GetAmmo(Hedgehog: PHedgehog): TAmmoType;
 function  GetUtility(Hedgehog: PHedgehog): TAmmoType;
 procedure HideHog(HH: PHedgehog);
-procedure RestoreHog(HH: PHedgehog);
 procedure ProcessGears;
 procedure EndTurnCleanup;
 procedure SetAllToActive;
--- a/hedgewars/uTeams.pas	Thu Jun 13 22:04:22 2013 +0200
+++ b/hedgewars/uTeams.pas	Thu Jun 13 22:27:23 2013 +0200
@@ -20,8 +20,8 @@
 
 unit uTeams;
 interface
-uses uConsts, uInputHandler, uGears, uRandom, uFloat, uStats, uVisualGears, uCollisions, GLunit,
-     uSound, uStore, uTypes
+uses uConsts, uInputHandler, uRandom, uFloat, uStats, uVisualGears,
+     uCollisions, GLunit, uSound, uStore, uTypes, uScript
      {$IFDEF USE_TOUCH_INTERFACE}, uWorld{$ENDIF};
 
 
@@ -34,6 +34,8 @@
 procedure InitTeams;
 function  TeamSize(p: PTeam): Longword;
 procedure RecountTeamHealth(team: PTeam);
+procedure RestoreHog(HH: PHedgehog);
+
 procedure RestoreTeamsFromSave;
 function  CheckForWin: boolean;
 procedure TeamGoneEffect(var Team: TTeam);
@@ -496,6 +498,17 @@
 AddVisualGear(0, 0, vgtTeamHealthSorter)
 end;
 
+procedure RestoreHog(HH: PHedgehog);
+begin
+    HH^.Gear:=HH^.GearHidden;
+    HH^.GearHidden:= nil;
+    InsertGearToList(HH^.Gear);
+    HH^.Gear^.State:= (HH^.Gear^.State and (not (gstHHDriven or gstInvisible or gstAttacking))) or gstAttacked;
+    AddGearCI(HH^.Gear);
+    HH^.Gear^.Active:= true;
+    ScriptCall('onHogRestore', HH^.Gear^.Uid)
+end;
+
 procedure RestoreTeamsFromSave;
 var t: LongInt;
 begin